iOS知识整理-Block

2019-10-15  本文已影响0人  皮皮蟹pipixie

Block是将函数及其执行上下文封装起来的对象

变量截获

局部变量截获 是值截获

NSInteger num = 3;
NSInteger(^block)(NSInteger) = ^NSInteger(NSInteger n){
       return n*num;
};
num = 1;
NSLog(@"%zd",block(2));  
// 输出是6而不是2,原因就是对局部变量num的截获是值截获。
NSMutableArray * arr = [NSMutableArray arrayWithObjects:@"1",@"2", nil];
void(^block)(void) = ^{
        NSLog(@"%@",arr);//局部变量
        [arr addObject:@"4"];
    };
[arr addObject:@"3"];
arr = nil;
block();
// 打印为1,2,3.因为block内部会截获arr,且引用修饰符相同。


局部静态变量截获 是指针截获

static  NSInteger num = 3;
NSInteger(^block)(NSInteger) = ^NSInteger(NSInteger n){
    return n*num;
};
num = 1;
NSLog(@"%zd",block(2));
// 输出为2,意味着num = 1这里的修改num值是有效的,即是指针截获。
// 同样,在block里去修改变量m,也是有效的。


全局变量,静态全局变量截获:不截获,直接取值。

static NSInteger num3 = 300;
NSInteger num4 = 3000;
- (void)blockTest {
    void(^block)(void) = ^{
        NSLog(@"%zd",num3);//全局变量
        NSLog(@"%zd",num4);//全局静态变量
    };
    block();
}
// 300, 3000

Block循环引用

当self持有Block,Block中又使用self时,就会产生循环引用。
解决办法:

  1. __weak来修饰self。当self有可能被释放时,可以在block内部再用__strong生成strongSelf;
    __weak typeof(self) weakSelf = self;
    self.setAlertBlock = ^(NSString *status) {
        __strong typeof(weakSelf) strongSelf = weakSelf;
    };
  1. 在block内部使用完self后,将其置为nil,但这种方式有个问题,如果block一直不被调用,那么循环引用将一直存在。所以,我们最好还是用__weak来修饰self。

参考:Block原理、Block变量截获、Block的三种形式、__block

上一篇 下一篇

猜你喜欢

热点阅读