block 深入浅出

2019-10-07  本文已影响0人  Bruce_XHG

2、为什么说 block 有捕获外部变量的能力(show the code

int a = 10;
    void (^block)() = ^{
        DebugLog(@"a = %d",a);
    };
    a++;
    block();
    DebugLog(@"a = %d",a);   
  • 输出结果分别是:10,11。这是为什么呢?这就是 block 的捕获外部变量的能力。那么 block 是如何捕获的呢,请在本文最后查看如何使用 clang 命令查看 block 内部实现,这里会讲述 block 是如何捕获外部变量。

3、block 在其声明的时候当在 MRC 的环境中使用 copy,当在 ARC 的环境中可使用 copy 也可以使用 strong。目前在 ARC 环境中我们一直还在使用 copy 的原因是延续了 MRC 时代的写法。

4、block 类型我们可以从两方面来说:一、内存分布上;二、声明上。

  • 内存分布上

__NSGlobalBlock 全局 block

void(^block)() = ^{
        DebugLog(@"block");
    };
    block();
    DebugLog(@"%@",block);
    
    block
Block1ViewController.m:60   
<__NSGlobalBlock__: 0x10089c110>

__NSStackBlock 栈 block

int a  = 10;
    void(^block)() = ^{
        DebugLog(@"block-%d",a);
    };
    block();
    DebugLog(@"%@",^{
        DebugLog(@"block-%d",a);
    });
    
    Block1ViewController.m:62   
<__NSStackBlock__: 0x16cf8ba20>

__NSMallocBlock 堆 block

int a  = 10;
    void(^block)() = ^{
        DebugLog(@"block-%d",a);
    };
    block();
    DebugLog(@"%@",block);
    
    block-10
Block1ViewController.m:59   
<__NSMallocBlock__: 0x283394ae0>

  • block声明上

无参数无返回值 void(^block)()

有参数无返回值 void(^block)(int a)

无参数有返回值 int(^block)()

有参数有返回值 int(^block)(int a,int b)

5、如何解决 block 的循环问题(有三种方法show the code)

1、 __weak __strong

__weak typeof(self)weakSelf = self;
    self.testBlock = ^{
        __strong typeof(weakSelf)strongSelf = weakSelf;
        [strongSelf doSomeThing];
    };
    self.testBlock();

2、__block

__block Block1ViewController *vc = self;
    self.testBlock = ^{
        [vc doSomeThing];
        vc = nil;
    };
    self.testBlock();

3、self 作为参数

self.testBlock = ^(Block1ViewController *vc){
        [vc doSomeThing];
    };
    self.testBlock(self);

6 __block修改局部变量 clang 查看内部实现 可以查看下图以及本文全部整理都在图中。

image
上一篇 下一篇

猜你喜欢

热点阅读