項(xiàng)目中的宏定義
<pre>
define kSelfWeak __weak typeof(self) weakSelf = self
define kSelfStrong __strong typeof(weakSelf) strongSelf = weakSelf
</pre>
正常我們?cè)谑褂胋lock時(shí)會(huì)寫(xiě)出如下的代碼:
<pre>
- (void)function{
kSelfWeak; //創(chuàng)建一個(gè)指向當(dāng)前對(duì)象的弱引用
[teseObject callFunc:^{
kSelfStrong; //block內(nèi)部定義一個(gè)指向當(dāng)前對(duì)象的強(qiáng)引用
[strongself callFunc_1:....];
[strongself callFunc_2:....];
....
}];
}
</pre>
現(xiàn)在我們來(lái)帶著問(wèn)題分析一下上面的這個(gè)代碼:
可不可以直接使用self?
不可以。因?yàn)檫@樣block會(huì)強(qiáng)持有self對(duì)象,造成循環(huán)引用,從而導(dǎo)致內(nèi)存泄露。可不可以直接使用weakself?
看情況。由于weakself不會(huì)持有對(duì)象,因此不會(huì)造成循環(huán)引用的問(wèn)題,但是使用weakself卻會(huì)造成block執(zhí)行不一致問(wèn)題,試想一下上面的代碼,當(dāng)調(diào)用“callFunc_1”的時(shí)候weakself是有效的,但是當(dāng)調(diào)用“callFunc_2”的時(shí)候weakself可能已經(jīng)是nil了,這樣就造成了block內(nèi)執(zhí)行不一致從而導(dǎo)致意想不到的結(jié)果循環(huán)引用是不是都是壞人?
答案是否定的。當(dāng)block開(kāi)始執(zhí)行的時(shí)候,strongself會(huì)去取self對(duì)象的值,如果此時(shí)self已經(jīng)為nil,那么整個(gè)block執(zhí)行期間strongself都是nil,如果self有效那么strongself就是利用了循環(huán)引用的特性保證了在block執(zhí)行的時(shí)候self對(duì)象不會(huì)被析構(gòu),保證block執(zhí)行的一致性。其實(shí)我們?cè)诰帉?xiě)業(yè)務(wù)代碼的時(shí)候(很多第三方開(kāi)源類庫(kù))中會(huì)利用到循環(huán)引用的這一特性來(lái)保證block中引用的對(duì)象在block執(zhí)行的時(shí)候依然有效,但是切忌使用這樣黑魔法的時(shí)候要在block執(zhí)行結(jié)束后打破循環(huán)引用。由于strongself是block內(nèi)部定義的變量,在block執(zhí)行結(jié)束會(huì)由系統(tǒng)回收從而打破循環(huán)引用
<pre>
總結(jié):使用strongself可以消除循環(huán)引用帶來(lái)的內(nèi)存泄漏,也可以保證block執(zhí)行過(guò)程中的一致性。所以正常的業(yè)務(wù)代碼我們都會(huì)使用上面的標(biāo)準(zhǔn)方式編寫(xiě),只有特殊的情況才會(huì)利用block的特性寫(xiě)一些黑魔法的代碼。
</pre>