-
block本質(zhì):
block本質(zhì)上也是一個OC對象,它內(nèi)部也有個isa指針
block是封裝了函數(shù)調(diào)用以及函數(shù)調(diào)用環(huán)境的OC對象
-
block的底層結構如右圖所示
-
block的變量捕獲(capture):
為了保證block內(nèi)部能夠正常訪問外部的變量弥锄,block有個變量捕獲機制
-
block的類型:
block有3種類型辉巡,可以通過調(diào)用class方法或者isa指針查看具體類型拴驮,最終都是繼承自NSBlock類型:
NSGlobalBlock ( _NSConcreteGlobalBlock )
NSStackBlock ( _NSConcreteStackBlock )
NSMallocBlock ( _NSConcreteMallocBlock )
每一種類型的block調(diào)用copy后的結果如下所示:
-
block的copy:
- 在ARC環(huán)境下楞陷,編譯器會根據(jù)情況自動將棧上的block復制到堆上韵洋,比如以下情況:
1.block作為函數(shù)返回值時
2.將block賦值給__strong指針時
3.block作為Cocoa API中方法名含有usingBlock的方法參數(shù)時
4.block作為GCD API的方法參數(shù)時
- 在ARC環(huán)境下楞陷,編譯器會根據(jù)情況自動將棧上的block復制到堆上韵洋,比如以下情況:
// MRC下block屬性的建議寫法
@property (copy, nonatomic) void (^block)(void);
// ARC下block屬性的建議寫法
@property (strong, nonatomic) void (^block)(void);
@property (copy, nonatomic) void (^block)(void);
-
對象類型的auto變量
當block內(nèi)部訪問了對象類型的auto變量時
如果block是在棧上捧颅,將不會對auto變量產(chǎn)生強引用如果block被拷貝到堆上
會調(diào)用block內(nèi)部的copy函數(shù)
copy函數(shù)內(nèi)部會調(diào)用_Block_object_assign函數(shù)
_Block_object_assign函數(shù)會根據(jù)auto變量的修飾符(__strong景图、__weak、__unsafe_unretained)做出相應的操作碉哑,形成強引用(retain)或者弱引用-
如果block從堆上移除
會調(diào)用block內(nèi)部的dispose函數(shù)
dispose函數(shù)內(nèi)部會調(diào)用_Block_object_dispose函數(shù)
_Block_object_dispose函數(shù)會自動釋放引用的auto變量(release)