美文网首页
iOS - Block的详解

iOS - Block的详解

作者: tigger丨 | 来源:发表于2016-01-11 19:10 被阅读362次

    一、Block的简单介绍

    Block 就是匿名函数 它是封装了一个代码块,这个代码块在什么时候都可以执行;

    使用Block的步骤就三步:1.定义Block变量;2创建Block的代码块 3.调用Block

    (1)无参无返回值

    void (^one) = ^{ NSLog(@"hello world!"); };   调用 one();

      (2)  无参有返回值

    int (^tow) = ^{ return 1; };  调用  int a = tow();

      (3)  有参无返回值

    void (^three)(int) = ^(int a){ NSLog(@"hello world!"); };  调用  int b = 2;  three(b);

      (4)  有参有返回值

    int (^four)(int,int) = ^(int a,int b){ return a + b;); };  调用 int a = 1; int b = 2; 

    int sum = four (a , b);

    定义Block的另一种方式 一般用 typedef void (^BlockName)( );

    二、Block的注意事项

    typedef void (^BlockName)( );

    1.调用Block的时候首先要判空 if (self.BlockName){ 在这里调用Block:self.BlockName( ) };

    2.Block可以访问局部变量,但是不能修改它的值如果要修改的话该变量必须用__block修饰

    int a = 10; void(^BlockName)() = ^{  a++;  }; 此处a的值不能修改

    原因:此处不能修改的原因是在编译期间确定的,编译器编译的时候把a的值复制到block作为一个新变量(假设是a‘ = 10),此时a'和a是没有关系的

    3.如果block块里边有self这样的代码, self必须用__weak 修饰;

    __self ViewController *controller = self;

    void(^BlockName)() = ^{  NSLog(@"%@", controller.string); };

    原因:block会对内部的对象进行一次retain,也就是说self会被retain一次。当self释放的时候,需要block释放后才会对self进行释放,但是block的释放又需要等self的dealloc中才会释放。如此一来变形成了循环引用,导致内存泄露。(一句话防止循环引用)

    4.在申明block属性的时候用copy 后者strong修饰;

    因为默认情况下,block是存档在栈中,可能被随时回收,需要copy到堆区一份,防止被释放掉;

    @property(copy,nonatomic)BlockName  myBlock;

    5、在多线程环境下(block中的weakSelf有可能被析构的情况下),需要先将self转为strong指针,避免在运行到某个关键步骤时self对象被析构。

    __weak __typeof(self)weakSelf =self;

    AFNetworkReachabilityStatusBlock callback= ^(AFNetworkReachabilityStatus status) {

    __strong __typeof(weakSelf)strongSelf=weakSelf;

    strongSelf.networkReachabilityStatus=status;if(strongSelf.networkReachabilityStatusBlock) {

    strongSelf.networkReachabilityStatusBlock(status);

    }

    };

    第四、五、六行,如果不转成strongSelf而使用weakSelf,后面几句话中,有可能在第四句执行之后self的对象可能被析构掉,然后后面的StausBlock没有执行,导致逻辑错误。

    这里边的typeof(self) 指的是任意类型 ,还有一点 析构这个词的解释

    需要注意的情况暂时能想到这么多!如还有其他请留言告诉我不甚感激!

    三、Block的使用

    Block的使用我就简单说几点应用场景,第一点 他可以传递参数,具体来说就是实现两个ViewController之间值的传递;

    第二点 他可以代替代理来使用;

    第三点 他可以作为变量来传值,一般在网络请求的时候用的比较多;

    四、Block的底层实现 因为它涉及到了数据结构方面的知识,我暂时看不懂;

    相关文章

      网友评论

          本文标题:iOS - Block的详解

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