block的相關(guān)記錄
block在創(chuàng)建的時(shí)候,它的內(nèi)存是分配在棧上的,所以說(shuō)block本身的作于域是屬于創(chuàng)建時(shí)候的作用域,一旦在創(chuàng)建時(shí)候的作用域外面調(diào)用block將導(dǎo)致程序崩潰。因?yàn)闂^(qū)的特點(diǎn)就是創(chuàng)建的對(duì)象隨時(shí)可能被銷(xiāo)毀,一旦被銷(xiāo)毀后續(xù)再次調(diào)用空對(duì)象就可能會(huì)造成程序崩潰,用copy修飾,把block從棧中拷貝到堆中,防止被釋放。
block有3種類(lèi)型:
_NSConcreteGlobalBlock:全局的靜態(tài) block,類(lèi)似函數(shù)。如果block里不獲取任何外部變量。或者的變量是全局作用域時(shí),如成員變量、屬性等; 這個(gè)時(shí)候就是Global類(lèi)型
_NSConcreteStackBlock:保存在棧中的 block,棧都是由系統(tǒng)管理內(nèi)存,當(dāng)函數(shù)返回時(shí)會(huì)被銷(xiāo)毀。__block類(lèi)型的變量也同樣被銷(xiāo)毀。為了不被銷(xiāo)毀,block會(huì)將block和_block變量從棧拷貝到堆。
_NSConcreteMallocBlock:保存在堆中的 block,堆內(nèi)存可以由開(kāi)發(fā)人員來(lái)控制。當(dāng)引用計(jì)數(shù)為 0 時(shí)會(huì)被銷(xiāo)毀。
block使用時(shí)的注意事項(xiàng)
1.block訪問(wèn)局部變量時(shí),相當(dāng)于是值拷貝,不能修改只能訪問(wèn)
2.當(dāng)局部變量被__block修飾時(shí),相當(dāng)于block也引用了這個(gè)外部的值,這個(gè)值是可以修改的
3.全局變量是可以在block中修改的。
block的相關(guān)疑問(wèn)
1.為什么局部變量的值要用__block修飾才能在block里面被修改?
因?yàn)榫植孔兞康闹翟诔隽俗饔糜驎r(shí)就會(huì)被銷(xiāo)毀,但被_block修飾的時(shí)候,相當(dāng)于block引用了它,所以就不會(huì)被釋放了
2.block 里 strong self 后,block 不是也會(huì)持有 self 嗎?而 self 又持有 block ,那不是又循環(huán)引用了?
在block里用strong引用,保證了持有引用的周期只在 block被執(zhí)行時(shí),閉包函數(shù)返回后就釋放了。而直接用強(qiáng)引用,持有引用的周期則是block的生命周期,就會(huì)循環(huán)引用了。
3.為什么block不用strong修飾符 而是copy?
strong修飾的block,系統(tǒng)默認(rèn)的處理方式也是copy。 但是為了保證行為和修飾符一樣,所以建議使用copy的修飾符。
4.為什么@strongify(self) 和 @weakify(self) 要配套使用?
因?yàn)檫@樣可以防止我們?cè)赽lock中使用self時(shí),self出現(xiàn)提前釋放的問(wèn)題。我們?cè)赽lock中使用strongify(self)就能保證在這個(gè)block的回調(diào)執(zhí)行完之前self是不會(huì)被釋放的。