一、block存儲(chǔ)的區(qū)域
1.stack棧? 這個(gè)系統(tǒng)自動(dòng)分配的?對(duì)棧上的block調(diào)用copy,每次會(huì)返回新復(fù)制到堆上的block的指針,同時(shí),所有__block變量都會(huì)被復(fù)制至堆一份(多次拷貝,只會(huì)生成一份)
2.heap堆? 這個(gè)程序員手動(dòng)分配的,需要手動(dòng)Block_release(testBlockHeap);對(duì)已經(jīng)位于heap上的block,再次調(diào)用copy,只會(huì)增加block的引用計(jì)數(shù)
3.全局區(qū) 這個(gè) copy后還是在全局區(qū)
對(duì)全局區(qū)的block調(diào)用copy,會(huì)返回原指針,并且這期間不處理任何東西(至少目前的內(nèi)部實(shí)現(xiàn)是這樣);
二、block中引用外部變量
1.如果需要在block中修改變量且這個(gè)變量不是靜態(tài)static修飾的變量,需要__block來修飾,應(yīng)為block在引用外部變量的時(shí)候會(huì)拷貝一份(static除外),在block里面變量其實(shí)是已經(jīng)拷貝的一份而不是原來的
三、循環(huán)引用
從這個(gè)圖里可以看出 block是這個(gè)obj的一個(gè)屬性 即:
obj -----強(qiáng)引用------》_block?
而block里面有self即obj本身,所以
_block-----強(qiáng)引用------》obj
這樣就造成的block和obj都不能釋放,只有打破這個(gè)循環(huán)才能釋放
__weak typeof(self) weakSelf =
self;? 所以一般暫時(shí)用self前這樣處理 在使用weakSelf
注:1.typeof()
請(qǐng)參考http://blog.csdn.net/zz_mm/article/details/46818575?
2.
這個(gè)是對(duì)block轉(zhuǎn)換中間代碼來理解block的??http://blog.sina.com.cn/s/blog_65a8ab5d0101c709.html
3.http://blog.devtang.com/2013/07/28/a-look-inside-blocks/?
四、block作為屬性,參數(shù)時(shí)的注意事項(xiàng)
1.block作為屬性
@property(nonatomic,copy)testBlockblock;?
這里一般使用copy,因?yàn)閎lock不copy的話是在棧上面,如果需要在block的聲明外使用block,需要將它c(diǎn)opy到heap上面去,不然block的生命周期和stack一致
2.block作為屬性傳遞時(shí)候,一般需要先copy一邊在傳遞?,他和作為屬性一樣,如果不copy,那block是在棧上面,而且block里面的屬性如果是局部的,出來作用域就會(huì)錯(cuò)誤,只有copy一份,這樣block也會(huì)把塔索引用的變量同樣的復(fù)制一份到heap上面去
最后附上一個(gè)block的小測(cè)試
?http://www.cocoachina.com/bbs/read.php?tid-152222-page-1.html?