block引用计数基本概述:
在block被销毁前,block会释放所有内部对象的引用计数,但是如果block被作为属性使用copy关键字,被复制到堆内存中,那么在block的引用计数变成0之前,就无法被销毁,那么内部使用的对象的引用计数+1,就无法释放,所以如果不对self使用weak关键字的话,在block中直接使用self,就会造成循环引用。
这里重点说一下Block内使用的外部weak变量,如何防止被释放问题
#import "SecondViewController.h"
@interface SecondViewController ()
@property (nonatomic,copy) void(^block)(void);
@end
@implementation SecondViewController
-(void)dealloc {
NSLog(@"dealloc");
}
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor blueColor];
[self makeView];
}
-(void)makeView {
UIButton * btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn setTitle:@"go back" forState:UIControlStateNormal];
btn.frame = CGRectMake(10, 100, 200, 50);
[self.view addSubview:btn];
btn.backgroundColor = [UIColor blueColor];
[btn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[btn addTarget:self action:@selector(btnAction:) forControlEvents:UIControlEventTouchUpInside];
self.block = [self getBlock];
}
-(void(^)(void))getBlock {
__weak typeof(self) weakSelf = self;
NSLog(@"mode1 = %@",self);
//如果不使用weak,直接在block块中使用self的话,引用计数+1,block执行结束的时候不能自动减去1
void(^block)(void) = ^{
//这里使用__strong关键字加1,会在block执行结束时自动减去
__strong typeof(weakSelf) ss = weakSelf;
//这里推迟3秒执行
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"mod = %@",ss);
});
};
return block;
}
-(void)btnAction:(UIButton *)btn {
self.block();
[self.navigationController popViewControllerAnimated:YES];
}
网友评论