本文共 2139 字,大约阅读时间需要 7 分钟。
@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,所以导致运行失败。
_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也不会被调用。
__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。转载地址:http://nzitl.baihongyu.com/