block 初探
2021-02-22 本文已影响0人
easy_luo
@interface SecondViewController ()
@property (nonatomic, copy) void(^block)(void);
@property (nonatomic, copy) NSString *name;
@end
@implementation SecondViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.navigationItem.title = @"SecondViewController";
[self functionC];
}
- (void)dealloc{
NSLog(@"SecondViewController dealloc");
}
- (void)functionC{
__weak typeof(self) weakSelf = self;//确保block封装对象弱引用self
self.block = ^{//NSMalloc block 堆block
__strong typeof(self) strongSelf = weakSelf;//1、确保block开始执行时,强引用self引用计数+1,防止往后执行中self被释放。2、同时强指针可以指针方式访问 成员的属性
strongSelf->_name = @"jack";
NSLog(@"call block set name");
};
void(^callBlock)(void) = ^{
__strong typeof(self) strongSelf = weakSelf;
if (strongSelf.block) {//self.block 不一定会执行,如果self提前释放了,self的block也就被释放了。但callBlock一定会被执行后才被释放,被dispatch_after 强引用着。
strongSelf.block();
}
};
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{//模拟网络请求异步回来
callBlock();//强引用+1
NSLog(@"call block");
});
}
@end
全局block, 栈block, 堆block
- (void)test{
__weak typeof(self) weakSelf = self;
void(^ __weak doWork)(void) = nil;
{
int a = 0;
void(^doWork1)(void) = ^{//左边捕获外部变量,__NSStackBlock__; 右边强引用,copy block,是__NSMallocBlock__
a;
weakSelf.name = @"90";
NSLog(@"=============2222");
};
doWork = doWork1;//弱引用赋值
}
doWork();// doWork1出了作用域后会调用block_release释放堆block, 会crash
int b = 5;
void(^ __weak doWork)(void) = ^{
b;
NSLog(@"__NSGlobalBlock__");
};
//doWork 没有截获任何外部变量,GlobalBlock。 self.block 对全局 doWork block 进行 copy,仍是全局 block
doWork();
NSLog(@"__p == %p",doWork);
self.block = doWork;
void(^ __weak doWork2)(void) = doWork;
NSLog(@"__p == %p",doWork2);
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(4 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// block();
});
}