ARC下NSStackBlock去哪了

作者: hanl001 | 来源:发表于2017-03-24 23:41 被阅读312次

我在 Objective-C中Block的类型 一文中说到MRC下有NSGlobalBlock、NSMallocBlock以及NSStackBlock三种类型的block,而ARC下是没有NSStackBlock类型的,在这里对其进行一个更正补充。


在RAC下,进行如下测试:

    CGFloat f = 1.1;
    
    NSLog(@"%@", ^{NSLog(@"%lf",f);});
    
    NSLog(@"%@",[^{NSLog(@"%lf",f);} copy]);
    
    void(^deliveryBlock)(void) = ^{NSLog(@"%lf",f);};
    NSLog(@"%@", deliveryBlock);

输出日志为

2017-03-24 22:20:22.526 testdemo[48961:588668] <__NSStackBlock__: 0x7fff525a8c20>
2017-03-24 22:20:22.526 testdemo[48961:588668] <__NSMallocBlock__: 0x60000005e420>
2017-03-24 22:20:22.527 testdemo[48961:588668] <__NSMallocBlock__: 0x60000005e420>

我发现,在直接打印block的时候,他的类型显示的还是NSStackBlock。而我们将这个block进行赋值之后,打印deliveryBlock的结果是NSMallocBlock类型。
也就是说,NSStackBlock类型在ARC下是存在,只是在对他进行赋值的时候,编译器将栈区的block拷贝到了堆区(赋值和copy在这里效果相同)。


至于原因

- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSObject *obj = [[NSObject alloc]init];
    void(^deliveryBlock)(void) = ^{
        NSLog(@"%@",obj);
    };
    [self didBlock:deliveryBlock];
}


- (void)didBlock:(void(^)(void)) block {
    NSLog(@"%@",block);
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        block();
    });
}

参照上方代码,假如deliveryBlock是NSStackBlock类型,如果我们把deliveryBlock当作方法参数传递到了另外一个方法,那么一旦deliveryBlock不在原来方法的调用栈,而新方法调用deliveryBlock的时机又不得而知,可能在新方法调用的时候deliveryBlock的时候堆区的obj已经被释放。即:ARC下编译器在NSStackBlock类型的block传递过程中进行了自动优化。


为了进一步验证,我做了如下测试

- (void)viewDidLoad {
    [super viewDidLoad];
    [self test:^{
       NSLog(@"%@",self.object);
    }];
}
- (void)test:(void(^)(void))block {
    NSLog(@"%@",block); //log: <__NSStackBlock__: 0x7fff5ef49b88>
}

当object作为self的属性时,object在整个vc的生命周期存在,故不会有脱离调用栈的问题,所以编译器没有将其自动拷贝到堆。

相关文章

  • ARC下NSStackBlock去哪了

    我在 Objective-C中Block的类型 一文中说到MRC下有NSGlobalBlock、NSMallocB...

  • 左手去哪了?手机去哪了?

    左手去哪了?手机去哪了? 音符写梦 2014-3-10 16:16 每天14:53, 我都会左手拿上锁和钥匙, 右...

  • 时间去哪了,心去哪了。

    很多时候,我们想的,并不是时间去哪了,而是心去哪了。 一年365天,一天24小时,一小时60分钟,一分钟60秒,这...

  • 去哪了

    18.5万,能想起来的有9.5万,不知道那九万去哪了(*゚゚)

  • 去哪了

    戳破天空的 一定是那声呐喊 穿过苍穹 向前飞 也许在前方某个地方 会看到 失踪的从前 多想停下来 听一听风中的歌 ...

  • 去哪了

    渭城的风不再吹在我的脸上 不知记忆最深处那片竹林是否依然完好 奔跑的背影 追逐的男孩 你们都去哪儿了 冷落的球场 ...

  • 去哪了?

    我在过去的信里 寻找回忆 和你的那场相识 耗尽我所有的运气 隐隐作痛的回忆 不能这样烟消云散 一定还有别的原因 锁...

  • 去哪了?

    那个曾今坚持, 专注,爱笑爱说的你去哪里了?每天浪费时间,唯唯诺诺,无精打采,谁会爱你,谁会喜欢你?我希望你沟沟抖...

  • 去哪了

    今天发布的文章怎么不见了,好奇怪,已经两篇文章了,这是第三篇,我还从新下载了app!

  • 去哪了?

    今天是下午起床之后发现老爸不在家,老妈还在睡觉,我就想爸爸也许是出去散步,也许是出去买东西,其实我还纳闷呢,为啥我...

网友评论

    本文标题:ARC下NSStackBlock去哪了

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