iOS知识整理-Block

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容