block的本質(zhì)
block本質(zhì)上也是一個(gè)OC對象,它內(nèi)部也有個(gè)isa指針。block是封裝了函數(shù)調(diào)用以及函數(shù)調(diào)用環(huán)境的OC對象。
block的變量捕獲(capture)
為了保證block內(nèi)部能夠正常訪問外部的變量,block有個(gè)變量捕獲機(jī)制。
例子:

block的類型
block有3種類型,可以通過調(diào)用class方法或者isa指針查看具體類型,最終都是繼承自NSBlock類型。
1、NSGlobalBlock ( _NSConcreteGlobalBlock )全局區(qū)
2、NSStackBlock ( _NSConcreteStackBlock )堆區(qū)
3、NSMallocBlock ( _NSConcreteMallocBlock )棧區(qū)

每一種類型的block調(diào)用copy后的結(jié)果如下所示

對象類型的auto變量
當(dāng)block內(nèi)部訪問了對象類型的auto變量時(shí):
如果block是在棧上:將不會對auto變量產(chǎn)生強(qiáng)引用。
如果block被拷貝到堆上:
1、會調(diào)用block內(nèi)部的copy函數(shù)。
2、copy函數(shù)內(nèi)部會調(diào)用_Block_object_assign函數(shù)。
3、_Block_object_assign函數(shù)會根據(jù)auto變量的修飾符(__strong、__weak、__unsafe_unretained)做出相應(yīng)的操作,形成強(qiáng)引用(retain)或者弱引用。
如果block從堆上移除
1、會調(diào)用block內(nèi)部的dispose函數(shù)。
2、dispose函數(shù)內(nèi)部會調(diào)用_Block_object_dispose函數(shù)。
3、Block_object_dispose函數(shù)會自動(dòng)釋放引用的auto變量(release)。
__block修飾符
__block可以用于解決block內(nèi)部無法修改auto變量值的問題,__block不能修飾全局變量、靜態(tài)變量(static),編譯器會將__block變量包裝成一個(gè)對象。

__block的內(nèi)存管理
當(dāng)block在棧上時(shí),并不會對__block變量產(chǎn)生強(qiáng)引用。
當(dāng)block被copy到堆時(shí),會調(diào)用block內(nèi)部的copy函數(shù),copy函數(shù)內(nèi)部會調(diào)用_Block_object_assign函數(shù),_Block_object_assign函數(shù)會根據(jù)所指向?qū)ο蟮男揎椃╛_strong、__weak、__unsafe_unretained)做出相應(yīng)的操作,形成強(qiáng)引用(retain)或者弱引用(注意:這里僅限于ARC時(shí)會retain,MRC時(shí)不會retain)。


__block的__forwarding指針

循環(huán)引用問題
ARC
用__weak、__unsafe_unretained解決

MRC
用__unsafe_unretained解決
用__block解決