一 、Block的內(nèi)存泄露體現(xiàn)
block在copy時(shí)都會(huì)對(duì)block內(nèi)部用到的對(duì)象進(jìn)行強(qiáng)引用(ARC)或者retainCount增1(非ARC)酒贬。在ARC與非ARC環(huán)境下對(duì)block使用不當(dāng)都會(huì)引起循環(huán)引用問(wèn)題填大。 一般表現(xiàn)為: 1.某個(gè)類將block作為自己的屬性變量诽俯,然后該類在block的方法體里面又使用了該類本身顷牌,簡(jiǎn)單說(shuō)就是:
self.someBlock = ^(Type var){
[self dosomething];
self.otherVar = XXX;// 或者_(dá)otherVar = ...
};
block的這種循環(huán)引用會(huì)被編譯器捕捉到并及時(shí)提醒尼斧。(這個(gè)還是很人性化的)
// Created by 58 on 15/6/3.
// Copyright (c) 2015年 58. All rights reserved.
//
#import"TsetBlock.h"
void (^blockTest)(NSString *str,NSString *st );
typedefvoid (^blockT)(NSString *str,NSString *st );
@interfaceTsetBlock ()@property (nonatomic)NSArray *testArr;
@property (nonatomic ,copy)blockT block;
@end
@implementation TsetBlock
- (id)init{
if (self = [superinit]) {
self.testArr =@[@"你",@"覺(jué)",@"的",@"會(huì)",@"怎",@"樣"];
self.block = ^(NSString *name,NSString *str){
NSLog(@"arr:%@",self.testArr);
};
}
returnself;
}
@end
那么問(wèn)題來(lái)了:
Paste_Image.png
網(wǎng)上大部分帖子都表述為“block里面引用了self導(dǎo)致循環(huán)引用”霜旧,但事實(shí)真的是如此嗎冯吓?我表示懷疑棚潦,其實(shí)這種說(shuō)法是不嚴(yán)謹(jǐn)?shù)牧钇灰欢ㄒ@式地出現(xiàn)”self”字眼才會(huì)引起循環(huán)引用。我們改一下代碼丸边,不通過(guò)屬性self.arr去訪問(wèn)arr變量叠必,而是通過(guò)實(shí)例變量_arr去訪問(wèn),如下:
Paste_Image.png
很明顯了: 即使在你的block代碼中沒(méi)有顯式地出現(xiàn)”self”妹窖,也會(huì)出現(xiàn)循環(huán)引用纬朝!只要你在block里用到了self所擁有的東西!但對(duì)于這種情況骄呼,目前我不知道該如何排除掉循環(huán)引用共苛,因?yàn)槲覀儫o(wú)法通過(guò)加__weak聲明或者_(dá)_block聲明去禁止block對(duì)self進(jìn)行強(qiáng)引用或者強(qiáng)制增加引用計(jì)數(shù)。對(duì)于self.arr的情況谒麦,我們要分兩種環(huán)境去解決:
1.arc:__weaktypeof(self) weakSelf=self; 其實(shí) __weak someClass *weakSelf = self也是OK的6矶铩6咧隆绕德!
2.MRC:解決方式與上述基本一致,只不過(guò)將__weak關(guān)鍵字換成__block即可摊阀,這樣的意思是告訴block:孫子耻蛇,咱們已經(jīng)沒(méi)有關(guān)系了(不要在內(nèi)部對(duì)self進(jìn)行retain了)踪蹬!