美文网首页iOS技术专题知识积累将来跳槽用
关于 block 会不会被自动 copy 的实验和猜想

关于 block 会不会被自动 copy 的实验和猜想

作者: 戴仓薯 | 来源:发表于2017-02-06 17:54 被阅读906次

今天群里不知怎么说起了 block 在栈上还是在堆上的问题。好像之前在哪里看到过,现在 block 的属性已经不用写 copy 关键字,就会自动 copy。于是做了几个实验,想看看什么情况下会自动 copy,什么情况下不会~

实验

代码如下:

TestClass.h
typedef void(^SimpleBlock)();

@interface TestClass : NSObject

@property (nonatomic, copy) SimpleBlock copyProperty;

@property (nonatomic, strong) SimpleBlock strongProperty;

@property (nonatomic, weak) SimpleBlock weakProperty;

@property (nonatomic, assign) SimpleBlock assignProperty;

@end
main
#import "TestClass.h"

SimpleBlock someFunction(SimpleBlock block) {
    NSLog(@"block as param : %@", block);
    return block;
}

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
        __block int a = 1;
        
        NSLog(@"orginal block : %@", ^{
            a = 2;
        });
        
        // as a variable
        SimpleBlock block = ^{
            a = 2;
        };
        NSLog(@"block as variable : %@", block);
        __weak SimpleBlock weakBlock = ^{
            a = 2;
        };
        NSLog(@"block as a weak variable : %@", weakBlock);
        
        // as properties
        TestClass* testClass = [TestClass new];
        testClass.weakProperty = ^{
            a = 2;
        };
        testClass.assignProperty = ^{
            a = 2;
        };
        testClass.copyProperty = ^{
            a = 2;
        };
        testClass.strongProperty = ^{
            a = 2;
        };
        
        NSLog(@"copy property : %@", testClass.copyProperty);
        NSLog(@"strong property : %@", testClass.strongProperty);
        NSLog(@"weak property : %@", testClass.weakProperty);
        NSLog(@"assign property : %@", testClass.assignProperty);
        
        NSLog(@"block as return value : %@", someFunction(^{
            a = 2;
        }));
    }
    return 0;
}

实验结果:

2017-02-06 17:43:36.207212 test2[27378:1079138] orginal block : <__NSStackBlock__: 0x7fff5fbff728>
2017-02-06 17:43:36.207436 test2[27378:1079138] block as variable : <__NSMallocBlock__: 0x100402f70>
2017-02-06 17:43:36.207457 test2[27378:1079138] block as a weak variable : <__NSStackBlock__: 0x7fff5fbff6b8>
2017-02-06 17:43:36.207492 test2[27378:1079138] copy property : <__NSMallocBlock__: 0x100403140>
2017-02-06 17:43:36.207517 test2[27378:1079138] strong property : <__NSMallocBlock__: 0x100403170>
2017-02-06 17:43:36.207563 test2[27378:1079138] weak property : <__NSStackBlock__: 0x7fff5fbff668>
2017-02-06 17:43:36.207581 test2[27378:1079138] assign property : <__NSStackBlock__: 0x7fff5fbff640>
2017-02-06 17:43:36.207611 test2[27378:1079138] block as param : <__NSStackBlock__: 0x7fff5fbff618>
2017-02-06 17:43:36.207769 test2[27378:1079138] block as return value : <__NSMallocBlock__: 0x100600000>

分析

  • 作为变量:
    • 一个 block 刚声明的时候是在栈上
    • 赋值给一个普通变量之后就会被 copy 到堆上
    • 赋值给一个 weak 变量不会被 copy
  • 作为属性:
    • 用 strong 和 copy 修饰的属性会被 copy
    • 用 weak 和 assign 修饰的属性不会被 copy
  • 函数传参:
    • 作为参数传入函数不会被 copy
    • 作为函数的返回值会被 copy

猜测

看着以上结论,感觉可以做出一个猜测:就是 block 被 retain 的时候就会自动被 copy,包括 autoRelease~ 这样就能解释为啥函数的参数不会被 copy,返回值就会被 copy。是不是很有道理呢 =w=

相关文章

  • 关于 block 会不会被自动 copy 的实验和猜想

    今天群里不知怎么说起了 block 在栈上还是在堆上的问题。好像之前在哪里看到过,现在 block 的属性已经不用...

  • OC中的copy

    1.所有被copy修饰的对象都会进行深copy吗? 答案:NO,例如block 全局block被copy修饰不会有...

  • __block在 ARC和MRC的影响

    __block 在ARC中使用时,不管对象还是自动变量Block内都会深copy一份,地址与copy对象地址不同,...

  • Copy 和 MutableCopy

    日志输出 Copy 和 MutableCopy block为什么要使用copy block使用copy是在MRC中...

  • 3. __block  __weak  __strong   这

    1.1 局部变量 局部自动变量,在Block中可被读取。Block定义时copy变量的值,在Block中作为常量使...

  • 关于block(4)

    关于block(4) 标签: iOS 技术 接上篇,我们继续探究block。 block的copy属性 研究到这里...

  • iOS开发小知识笔记 (2)Block

    Bolck 在 ARC 中编译器会自动对 block 进行 copy 操作,但是苹果仍然建议使用 copy 来指明...

  • Objective - C block(三)block的copy

    (一)copy ARC环境下,编译器会根据情况自动将stackblock进行copy操作,复制到堆上 block作...

  • Block深入浅出 (二)

    这篇文章继续上一篇Block深入浅出 (一)讲解block的存储和copy问题 三 Block的存储和copy...

  • iOS block的一些理解和注意点

    block的定义:带有自动变量(局部变量)的匿名函数。 一.block作为参数使用时应该使用copy来修饰。 原因...

网友评论

  • WellCheng:主要是看当前的这个 block 会不会出 stack frame,把握这一点就很容易理解了。
  • 红枫叶HM:仓薯姐,看见文章开头提到了群,能告诉我群号吗,我也想进去看看大神们都是怎么解决问题的,多学习学习。我现在还是iOS入门者
  • Jacob_LJ:请教一个小白问题:有哪些开发场景因不注意block 的实际类型而导致潜在问题的发生?
  • 025fb4f9512a:感谢作者 不过这几天才看一本 ios高级编程 里面提及并讲解到了这个问题
    希望可以对楼主有帮助 封面是一个狮子头的 版本有点稍微旧了 但是里面讲的东西不错
  • Little_Mango:简主可以翻翻我写的《栈块、堆块、全局块》这一篇文章,然后建议适当修改本章的部分内容,素我直言,这篇文章的观点和结论存在不少问题,应该修改完善再发布出来,大家一起进步:smile:
  • kamous:ARC下大多数情况,编译器都会自动为block进行copy(比如函数返回的时候),但是block作为参数传入函数的时候例外。Cocoa框架名中有userBlock的API和GCD的API,有block参数传入的时候方法内会自动对block copy,其它的接口就不会自动copy block参数了,需要调用者传入block前自己调用copy
  • kamous:这几天刚好看到,和最后的结论有点不一致。ARC下,函数返回的block被copy,不是autoRelease的功劳,是编译器在把block添加才autorelease前,自动生成了copy的代码
    戴仓薯:原来是这样~ 长姿势了哈哈
    kamous:把block添加到autoreleasepool前。。
  • R0b1n_L33:赢取思婷~

    补充题外话:全局变量是__NSGlobalBlock__类型不变
    戴仓薯:是的,所以测试时候捕捉了一个 __block 变量,让它不是全局变量:)

本文标题:关于 block 会不会被自动 copy 的实验和猜想

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