block為什麼用copy以及如何解決迴圈引用

2022-07-27 23:33:35 字數 934 閱讀 4269

在完成專案期間,不可避免的會使用到block,因為block有著比delegate和notification可讀性更高,而且看起來**也會很簡潔。於是在目前的專案中大量的使用block。

)主要是因為在開發的時候,有時候由於疏忽大意或者一些其他的原因,導致了使用block時造成了迴圈引用從而導致了記憶體洩露。

block 迴圈引用的主要原因:在block中引用了外部變數。

brush.getcardinfo

=^(nsdictionary *info);

像上面這段**,self其實是乙個本地變數而不是block內部變數,如果宣告為assign,**執行到block內部就會出錯。

但是這又帶來另乙個問題,就是self的引用計數+1。這意味著很可能會導致迴圈引用。self持有brush,brush持有block,block持有self。結果就是記憶體洩漏。

解決方法:

__weak currentviewcontroller *blockself = self; 

brush.getcardinfo

=^(nsdictionary *info)

;通過__weak修飾變數這個方式,告訴block這個變數的引用計數不要+1。從而避免迴圈引用的問題。

宣告block的時候都是用copy來修飾

使用copy修飾的原因:

block本身是像物件一樣可以retain,和release。但是,block在建立的時候,它的記憶體是分配在棧(stack)上,而不是在堆(heap)上。他本身的作於域是屬於建立時候的作用域,一旦在建立時候的作用域外面呼叫block將導致程式崩潰。

使用retain也可以,但是block的retain行為預設是用copy的行為實現的,因為block變數預設是宣告為棧變數的,為了能夠在block的宣告域外使用,所以要把block拷貝(copy)到堆,所以說為了block屬性宣告和實際的操作一致,最好宣告為copy。

Block為什麼用copy修飾

預設情況下,block是存檔在棧中,可能被隨時 通過copy操作可以使其在堆中保留乙份,相當於一直強引用著,因此如果block中用到self時,需要將其弱化,通過 weak或者 unsafe unretained.以下是示例 及其說明,讀者可以試著列印出不同情況下block的記憶體情況 viewco...

block為什麼用copy以及如何解決迴圈引用

在完成專案期間,不可避免的會使用到block,因為block有著比delegate和notification可讀性更高,而且看起來 也會很簡潔。於是在目前的專案中大量的使用block。但是在開發的時候,有時候由於疏忽大意或者一些其他的原因,導致了使用block時造成了迴圈引用從而導致了記憶體洩露。b...

從堆疊剖析block為什麼用copy

1.首先理解連個概念 堆 heap heap的空間需要手動分配。heap 與動態記憶體分配相關 記憶體可以隨時在堆中分配和銷毀。我們需要明確請求記憶體分配與記憶體銷毀。簡單來說,就是malloc與free.棧 stack stack的空間由作業系統進行分配。在現代作業系統中 乙個執行緒會分配乙個 s...