Block 03 - 內(nèi)存管理
Block 的 copy
-
在 ARC 環(huán)境下凭疮,編譯器會(huì)根據(jù)情況自動(dòng)將棧上的 Block 復(fù)制到堆上:
- Block 作為函數(shù)返回值時(shí)。
- 將 Block 賦值給 __strong 指針時(shí)偶垮。
- Block 作為 Cocoa API 中方法名含有 UsingBlock 的方法參數(shù)時(shí)。
- Block 作為 GCD API 的方法參數(shù)時(shí)帝洪。
在 MRC 環(huán)境下 Block 屬性的建議寫(xiě)法:
@property(nonatomic, copy) void (^block)(void);
在 ARC 環(huán)境下 Block 屬性的建議寫(xiě)法:
@property(nonatomic, strong) void(^block)(void);
@property(nonatomic, copy) void(^block)(void);
當(dāng) Block 內(nèi)部訪問(wèn)了對(duì)象類(lèi)型的 auto 變量似舵、__block 對(duì)象時(shí)
- 當(dāng) Block 在棧上時(shí),對(duì)它們都不會(huì)進(jìn)行強(qiáng)引用葱峡。
- 當(dāng) Block 被拷貝到堆上時(shí):
- 會(huì)調(diào)用 Block 內(nèi)部的 copy 函數(shù)砚哗。
- copy 函數(shù)內(nèi)部會(huì)調(diào)用 _Block_object_assign 函數(shù)。
- _Block_object_assign 函數(shù)會(huì)對(duì) __block 對(duì)象進(jìn)行強(qiáng)引用砰奕。
- _Block_object_assign 函數(shù)會(huì)根據(jù) auto 變量的修飾符(__strong, __weak, __unsafe_unretained)做出相應(yīng)的操作蛛芥,進(jìn)行強(qiáng)引用(retain)或弱引用提鸟。
- 當(dāng) Block 從堆上移除時(shí):
- 會(huì)調(diào)用 Block 內(nèi)部的 dispose 函數(shù)。
- dispose 函數(shù)內(nèi)部會(huì)調(diào)用 _Block_object_dispose 函數(shù)仅淑。
- _Block_object_dispose 函數(shù)會(huì)自動(dòng)釋放被強(qiáng)引用的對(duì)象(release)称勋。
_Block_object_assign((void*)&dst->o, (void*)src->o, 3/*BLOCK_FIELD_IS_OBJECT*/); _Block_object_assign((void*)&dst->b, (void*)src->b, 8/*BLOCK_FIELD_IS_BYREF*/); _Block_object_dispose((void*)src->o, 3/*BLOCK_FIELD_IS_OBJECT*/); _Block_object_dispose((void*)src->b, 8/*BLOCK_FIELD_IS_BYREF*/);
代碼中如果使用了 __weak,在使用 clang 將 Objective-C 轉(zhuǎn)換為 C++ 時(shí)漓糙,會(huì)有以下問(wèn)題:
cannot create __weak reference in file using manual reference解決方式(在命令中指定支持 ARC铣缠、運(yùn)行時(shí)系統(tǒng)版本):
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc ==-fobjc-arc== ==-fobjc-runtime=ios-8.0.0== class.m -o class.cpp
__block 對(duì)象的內(nèi)存管理
- 當(dāng) __block 對(duì)象在棧上時(shí),不會(huì)對(duì)被包裝的變量指向的對(duì)象進(jìn)行強(qiáng)引用昆禽。
- 當(dāng) __block 對(duì)象被拷貝到堆上時(shí):
- 會(huì)調(diào)用 __block 對(duì)象內(nèi)部的 __Block_byref_id_object_copy 函數(shù)蝗蛙。
- __Block_byref_id_object_copy 函數(shù)內(nèi)部會(huì)調(diào)用 _Block_object_assign 函數(shù)。
- _Block_object_assign 函數(shù)會(huì)根據(jù)變量的修飾符(__strong醉鳖、__weak捡硅、__unsafe_unretained)做出相應(yīng)的操作,進(jìn)行強(qiáng)引用(retain盗棵,僅限于 ARC 環(huán)境)或弱引用壮韭。
- 當(dāng) __block 對(duì)象從堆上移除時(shí):
- 會(huì)調(diào)用 __block 變量?jī)?nèi)部的 __Block_byref_id_object_dispose 函數(shù)。
- __Block_byref_id_object_dispose 函數(shù)內(nèi)部會(huì)調(diào)用 _Block_object_dispose 函數(shù)纹因。
- _Block_object_dispose 函數(shù)會(huì)自動(dòng)釋放被強(qiáng)引用的對(duì)象(release)喷屋。