Block为什么使用copy修饰

Block分为全局Block、堆Block和栈Block

1 先将工程中的ViewController切换到MRC模式:

切换方法:
在工程Build Phases的Compile Sources中,将需要切换为MRC的类文件后加上-fno-objc-arc即可

ARC和MRC混编.png

2 定义三个无参无返回值类型的Block,分别打印Block的内存地址

- (void)viewDidLoad {
    [super viewDidLoad];
   
    //__NSGlobalBlock__ 全局区的 (没有引用外部变量)
    void (^DemoBlock)() = ^{
        NSLog(@"DemoBlock");
    };
    NSLog(@"%@",DemoBlock);
    
    int a = 6;
    //__NSStackBlock__ 栈区 (内部使用了外部变量)(MRC模式下)
    void (^DemoBlock2)() = ^{
        NSLog(@"DemoBlock2 %d",a);
    };
    NSLog(@"DemoBlock2 %@",DemoBlock2);

    //__NSMallocBlock__ 堆区 ([DemoBlock2 copy]后Block存放在堆区)
    NSLog(@"DemoBlock2.Copy %@",[DemoBlock2 copy]);

    void (^DemoBLock3)() = [DemoBlock2 copy];
    NSLog(@"DemoBlock3 %@",DemoBLock3);
}

Log信息:

2016-06-13 19:11:03.712 02-Block为什么使用copy修饰[10956:548330] DemoBlock:<__NSGlobalBlock__: 0x100d2b0a0>
2016-06-13 19:11:03.713 02-Block为什么使用copy修饰[10956:548330] DemoBlock2 <__NSStackBlock__: 0x7fff5eed4950>
2016-06-13 19:11:03.713 02-Block为什么使用copy修饰[10956:548330] DemoBlock2.Copy <__NSMallocBlock__: 0x7ff1a9d19270>
2016-06-13 19:11:03.713 02-Block为什么使用copy修饰[10956:548330] DemoBlock3 <__NSMallocBlock__: 0x7ff1a9d9c590>

分析:

  • DemoBlock内部没有调用外部变量时存放在全局区(ARC和MRC下均是)
  • DemoBlock2使用了外部变量,这种情况也正式我们平时所常用的方式,Block的内存地址显示在栈区,栈区的特点就是创建的对象随时可能被销毁,一旦被销毁后续再次调用空对象就可能会造成程序崩溃,在对block进行copy后,block存放在堆区.所以在使用Block属性时使用Copy修饰,而在ARC模式下,系统也会默认对Block进行copy操作
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 前言 Blocks是C语言的扩充功能,而Apple 在OS X Snow Leopard 和 iOS 4中引入了这...
    小人不才阅读 3,791评论 0 23
  • #C语言内存分配 Objective-C从名字来看就可以知道是一门超C语言,所以了解C语言的内存模型对于理解Obj...
    吾是小马哥阅读 1,440评论 0 10
  • 《Objective-C高级编程》这本书就讲了三个东西:自动引用计数、block、GCD,偏向于从原理上对这些内容...
    WeiHing阅读 9,950评论 10 69
  • 11.看下面的程序,第一个NSLog会输出什么?这时str的retainCount是多少?第二个和第三个呢? 为什...
    AlanGe阅读 767评论 1 4
  • *面试心声:其实这些题本人都没怎么背,但是在上海 两周半 面了大约10家 收到差不多3个offer,总结起来就是把...
    Dove_iOS阅读 27,239评论 30 472