美文网首页
iOS知识整理-Block

iOS知识整理-Block

作者: 皮皮蟹pipixie | 来源:发表于2019-10-15 14:56 被阅读0次

    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

    相关文章

      网友评论

          本文标题:iOS知识整理-Block

          本文链接:https://www.haomeiwen.com/subject/zulsmctx.html