美文网首页
Block使用相关问题小记

Block使用相关问题小记

作者: 天蚕 | 来源:发表于2016-08-29 18:16 被阅读52次

    1、block做为属性为什么使用copy

    首先,要明确的是在ARC下block作为属性采用copy和strong策略效果是一样的,标题这句话只适用于MRC,在ARC下任然使用copy可以认为是一种习惯,没有什么特殊意义,用strong也不会错。

    • 1)所谓的外部变量引用(变量捕获)
      是指block在使用到block的{}之外定义的变量(外部变量)时,会将外部变量拷贝到堆上,通常情况下这里的拷贝只是简单的值传递,只有当该变量用__block修饰的时候才是址传递,所以如果想要在block内重新赋值给外部变量都需要__block修饰(但是当捕获的外部变量是全局变量,静态变量,或者捕获到的变量是某个对象的成员变量或者属性除外)
    NSMutableArrary *arrary = [NSMutableArrary arrary];
    void(^block)() = ^{
        [arrary addObject:@"呵呵呵"];
    };
    block();
    NSLog("%@",arrary);
    //输出'("呵呵呵")'
    
    Person *person = [[Person alloc] init];
    void(^block1) = ^{
        person.name = @"葛二蛋";
    };
    block1();
    NSLog("%@",person.name);
    //输出'葛二蛋'
    
    self.count = 10;
    void(block2) = ^{
        self.count = 10000;
    };
    block2();
    NSLog("%zd",self.count);
    
    • 2)block的存储区域
      block有3种类型
      __NSGlobalBlock__类型block存储在全局区
      __NSStackBlock__类型的block存储在栈区
      __NSMallocBlock__类型的block存储在堆区
      在MRC的下默认的block是__NSGlobalBlock__类型,引用了外部变量 (非全局变量和静态变量)的block是__NSStackBlock__类型,对__NSStackBlock__类型的block做copy操作,block将会被拷贝到堆区变成__NSMallocBlock__类型,而__NSGlobalBlock__类型的block做copy操作是无效的。
      在ARC下会默认的block也是__NSGlobalBlock__类型,引用了外部变量(非全局变量和静态变量)的block也是__NSStackBlock__类型,同样对__NSGlobalBlock__类型的block做copy操作也是无效的。
      ARC和MRC的block的区别在于ARC下的block在赋值的时候编译器会对strong和copy策略的block自动做copy操作后赋值,所以ARC的block作为属性的时候只需要采用strong或者copy策略,引用了外部变量的block就会是__NSMallocBlock__类型的在堆区存储,而没有采用strong或者copy策略和没有引用外部变量的block就是__NSGlobalBlock__类型的存储在全局区域。

    2、block书写习惯

    • 1)代码简洁
      block的等号右边尽量不要直接写出实现,建议创建新方法,在实现中调用创建的新方法,这样代码会显得更加简洁。比如在UITableviewcell中做回调的方法block,如果实现代码非常的长,而且cell的回调block不止一个,如果直接在UITableview的代理方法中实现block回调我们的代码将会很可怕。
    • 2)线程安全
      当block为nil的时候,直接调用block会造成崩溃,我们通常需要在调用block之前判空。但是由于block很可能会在我们判空之后,执行之前,被其他线程置空为nil,所以最保险的方法是,在判空之前将block用一个本地的临时变量缓存一份,然后再进行判空操作,就会避免多线程操作的不安全。
    • 3)循环引用
      通常为了避免block循环引用,我们会用weakself代替self,但是在多线程操作的时候,最好是将weakself做一次强引用,避免self在执行block操作之前被释放掉,一旦被释放self会被自动置为nil,此时block调用可能会没有反应。
      这篇大牛的文章很不错http://www.jianshu.com/p/ee9756f3d5f6

    相关文章

      网友评论

          本文标题:Block使用相关问题小记

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