iOS Bolck

7.7 Bolck

定义

  • 带有自动变量的匿名函数。本质是一个OC对象
  • 匿名函数:没有函数名的函数,一对{}包裹的内容是匿名函数的作用域。
  • 自动变量:栈上声明的一个变量不是静态变量和全局变量,是不可以在这个栈内声明的匿名函数中使用的,但在Block中却可以。
  • 虽然使用Block不用声明类,但是Block提供了类似Objective-C的类一样可以通过成员变量来保存作用域外变量值的方法,那些在Block的一对{}里使用到但却是在{}作用域以外声明的变量,就是Block截获的自动变量

内部结构

cc3d6b2b.jpg

c07ab3d5.jpg

表达式

  • ^ 返回值类型 (参数列表) {表达式}
    ^ int (int count) {
         return count + 1;
     };
    

Block类型变量

  • 返回值类型 (^变量名)(参数列表) = Block表达式
      int (^blk)(int) = ^(int count) {
         return count + 1;
     };
    

typedef声明Block

  • typedef 返回值类型 (^变量名)(参数列表)
     typedef void(^ResultBlock)(NSString *name, NSString *imgFilePath);
    //声明一个block变量
    @property (nonatomic, copy) ResultBlock result;
    

当Block类型变量作为函数的参数

- (void)setTimerWithId:(NSString *)tid  result:(void (^)(NSInteger code, NSDictionary *data))result;
}

- (void)func:(ResultBlock)blk {
  NSLog(@"Param:%@", blk);
}

Block类型变量作返回值

 - (void (^)(NSInteger code, NSDictionary *data))setTimerWithId:(NSString *)tid  ;
}

  - (ResultBlock)func:(NSString *)str {
    NSLog(@"Param:%@", str);
}

typedef int (^blk_k)(int);

- (blk_k)funcR {
    return ^(int count) {
        return count ++;
    };
}

Block的变量捕获(capture)

  • 为了保证Block内部能够真正访问外部的变量,Block有个变量捕获机制

  • 捕获:Block内部会新增一个成员变量来存储外部的值

  • 捕获的条件:判断是局部变量,还是全局变量,局部变量会捕获,全局变量不会捕获


    f98b8338.jpg
    • auto:作用域一过,就到销毁了,访问不到内存,所以block内部只能是指传递,在block外面不能修改。
    • static:类变量,类存在就不会被销毁,所以可以指针传递,在block外面不能修改。
    • 全局变量:不会捕获到block内部,可以直接访问

Block的类型

1a5f88df.jpg
  • 堆:动态分配内存,需要自己手动申请,需要自己管理内存
  • 栈:系统自动分配内存,系统自己会销毁
  • Global:没有访问auto变量
  • Stack:(MRC)访问了auto变量
  • malloc:Stack调用了copy
  • 每一种block调用了copy后的结果:


    d5c077b9.jpg

Block的copy

6302d07c.jpg

Block的对象类型的auto变量

  • 对象类型的auto变量,MRC下放到了栈空间,ARC下放到了堆空间
  • 栈空间的block不会拥有外面的对象的,对象在block释放之前,对象会被释放
  • 堆空间的block有能力去保住对象,对象在block释放之前,对象不会被释放
  • ARC:强引用默认做了copy操作,block放到了堆空间,如果对象用__weak修饰,对象会被释放,用__strong修饰,对象不会被释放
  • MRC:没有copy,block放到了栈空间
  • 3a7136e5.jpg

Block内部修改变量

  • 把局部变量改成全局变量
  • 用static修饰,把局部变量改成静态变量
  • 加__block修饰
    • 只能修饰局部变量,不能修饰全局变量和静态变量


      00adc437.jpg

__block的内存管理

b723414e.jpg

220ea1bd.jpg

对象类型的auto变量,__block变量

54105e54.jpg
  • forwarding的指向


    291ad043.png

block的循环引用

  • __weak:把一个设置成弱引用
  • __unsafe_unretain:和__weak,但是不不把引用对象设置为nil
  • __block:要调用block,并将对象设置为空。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 目录1.Block 的基本使用2.Block 的底层数据结构3.Block 的变量捕获机制3.1 auto 类型的...
    师大小海腾阅读 4,610评论 0 9
  • iOS开发---Block详解 Block的基础 什么是Blocks? 用一句话来描述:带有自动变量的匿名函数(是...
    祀梦_阅读 4,592评论 0 6
  • 先对block有一个基本的认识block本质上也是一个oc对象,他内部也有一个isa指针。block是封装了函数调...
    叫我小黑阅读 2,915评论 0 0
  • 一 block基本使用 二 block底层结构 三 block变量捕获 四 block的类型 五 block对象类...
    当前明月阅读 4,993评论 3 4
  • iOS开发---Block详解 Block的基础 什么是Blocks? 用一句话来描述:带有自动变量的匿名函数(是...
    萨缪阅读 1,391评论 0 0