Block深入浅出 (一)

一 概述

闭包就是1个函数或指向函数的指针+该函数的执行的上下文变量(也就是自由变量),Block是OC对于闭包的实现。其中Block可以定义在方法的内部或外部,其本质是对象,作用是使代码高聚合,只有调用Block的时候,才会调用代码块里的内容。

使用clang将OC代码转换为C++文件查看block的方法:

  • 在命令行输入代码 clang -rewrite-objc 需要编译的OC的.m文件(如果这步报错找不到UIKit,就是用这个命令生成 clang -x objective-c -rewrite-objc -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk 需要编译的OC的.m)
  • 这时查看当前的文件夹里 多了一个相同名称的 .cpp文件,可以在命令行输入 open 生成的.cpp 查看文件

开发中常用typedef定义一个block
void(^myBlock)(void);
使用时直接

@property (nonatomic, copy) myBlock blk;
self.blk = ^(){
        NSLog(@"typedef定义的block");
 };

定义一个无参数无返回值的block

void(^myBlock1)(void) = ^(){
        NSLog(@"我是无参无返回值block");
 };

定义一个有参数无返回值的block

void(^myBlock2)(NSString* string) = ^(NSString* string) {
        NSLog(@"我是有参数无返回值block");
 };

定义一个有参数有返回值的block

NSString*(^myBlock3)(NSString* string) = ^(NSString* string){
        return [string stringByAppendingString:@"我是有参数有返回值的block"];
 };

二 Block与外部变量

截取局部变量的值
  • 默认情况下,对于block外的变量引用,block是将其值复制到block内部的结构体中来访问的,也就是说block的自动变量的截取只针对block块内部使用的自动变量,不使用则不截取。特别注意默认情况下block只能访问不能修改局部变量的值。
   int a = 10;
    void(^myBlock)(void) = ^{
        NSLog(@"a的值是%d",a);
    };
    a = 20;
    myBlock();

输出结果为a=10,因为在a = 20赋值之前,a=10的值被截取到了block内部,a不管外部怎么变化,block内部的a永远都为10。

使用__block修饰的外部变量

对于用__block修饰的外部变量的引用,block是复制其引用地址来实现访问的,所以block内部可以修改__block修饰的外部变量的值。

    __block int a = 10;
    void(^myBlock)(void) = ^{
        NSLog(@"a的值是%d",a);
    };
    a = 20;
    myBlock();

输出结果为a=20
为什么__block修饰的外部变量的值就可以在block内部修改呢?
我们使用clang 将这个.m文件转成 .cpp查看一下

__attribute__((__blocks__(byref))) __Block_byref_a_0 a = {(void*)0,(__Block_byref_a_0 *)&a, 0, sizeof(__Block_byref_a_0), 10};
    void(*myBlock)(void) = ((void (*)())&__ViewController__viewDidLoad_block_impl_0((void *)__ViewController__viewDidLoad_block_func_0, &__ViewController__viewDidLoad_block_desc_0_DATA, (__Block_byref_a_0 *)&a, 570425344));
    (a.__forwarding->a) = 20;

发现局部变量a变成了__Block_byref_a_0结构体类型的自动变量实例

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

友情链接更多精彩内容