block循環引用解決
block循環引用解決
實驗代碼
@interface ViewController ()
@property (nonatomic, strong) TestNetworkBlock *testNetwork;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.testNetwork = [[TestNetworkBlock alloc] init];
[self.testNetwork ceshi];
[self.testNetwork release], self.testNetwork = nil;
}
@end
@interface TestNetworkBlock ()
{
countBlock _countBlock;
}
@property (nonatomic, strong) NSString *strTest;
@end
@implementation TestNetworkBlock
- (id) init
{
self = [super init];
if (self)
{
self.strTest = @"我的測試";
__weak TestNetworkBlock *weakSelf = self;
_countBlock = ^(int i){
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
sleep(5);
NSString *string = [weakSelf zhixing:i];
NSLog(@"string=====%@", string);
});
};
}
return self;
}
- (NSString *) zhixing:(int) i
{
NSString *string = [NSString stringWithFormat:@"%@%d", self.strTest, i];
return string;
}
- (void) ceshi
{
_countBlock(5);
}
- (void) dealloc
{
NSLog(@"======dealloc");
}
@end
問題剖析:
多線程調用,block外麵聲明了weakSelf,則block內部對self的引用為指針引用,當外部[self.testNetwork release], self.testNetwork = nil;時,weakSelf為nil,所以導致運行失敗。
第二種:block改為self引用
_countBlock = ^(int i){
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
sleep(5);
NSString *string = [self zhixing:i];
NSLog(@"string=====%@", string);
});
};
問題剖析
_countBlock為self對象,self強引用了_countBlock,同時_countBlock又怕裏麵self釋放,所以block體裏麵會強引用self。導致循環引用,內存一直不會被釋放,dealloc也不會被調用。
正確做法:block內部加入bSelf強引用指針
__weak TestNetworkBlock *weakSelf = self;
_countBlock = ^(int i){
TestNetworkBlock *bSelf = weakSelf;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
sleep(5);
NSString *string = [bSelf zhixing:i];
NSLog(@"string=====%@", string);
});
};
問題剖析
在 block 之前定義對 self 的一個弱引用 wSelf,因為是弱引用,所以當 self 被釋放時 wSelf 會變為nil;
在block體內部聲明一個強引用對象bself指向該wSelf。bSelf隻會在block內部執行完畢才會消亡,這樣就保證了self對象被外部其他線程釋放掉的情況。又避免了循環引用,因為在block執行完,會釋放掉bSelf。
最後更新:2017-08-13 22:34:03