考虑到多线程情况,通过使用强引用 self 来引用该弱引用,这时如果 self 不为 nil 就会 retain self,以防止在后面的使用过程中 self 被释放;然后在之后的 block 块中使用该强引用 self,注意在使用前要对 self 进行了 nil 检测,因为多线程环境下在用弱引用 wself 对强引用 self 赋值时,弱引用 wself 可能已经为 nil 了。
通过这种手法,block 就不会持有 self 的引用,从而打破了循环引用。
第一种解决方法(strong weak dance)
//strong weak dance
typedef void (^LGBlock) (void);
@interface ViewController ()
@property (nonatomic,copy) LGBlock block;
@property (nonatomic,copy) NSString *name;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.name = @"Silence";
__weak typeof(self) weakSelf = self;
self.block = ^{
__strong typeof(self) strongSelf = weakSelf;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
strongSelf.name = @"longge";
NSLog(@"%@",strongSelf.name);
});
};
self.block();
}
第二种方法(__block)
typedef void (^LGBlock) (void);
@interface ViewController ()
@property (nonatomic,copy) LGBlock block;
@property (nonatomic,copy) NSString *name;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.name = @"Silence";
__block ViewController *vc = self;
self.block = ^{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"%@",vc.name);
vc = nil;
});
};
self.block();
}
第三种方法(作为参数)
typedef void (^LGBlock) (ViewController *);
@interface ViewController ()
@property (nonatomic,copy) LGBlock block;
@property (nonatomic,copy) NSString *name;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.name = @"Silence";
self.block = ^(ViewController *vc) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"%@",vc.name);
});
};
self.block(self);
}
网友评论