说明:
<1>阅读本文,最好阅读之前的block文章加以理解;
<2>本文内容:三种block类型的copy情况(MRC)、是否深拷贝、错误copy;
一、MRC模式下,三种block类型的copy情况
//代码
void test1() { int age = 10; void(^block1)(void) = ^{ NSLog(@"-----"); }; void(^block2)(void) = ^{ NSLog(@"-----%d", age); }; id block3 = [block2 copy]; NSLog(@"%@ %@ %@", [block1 class], [block2 class], [block3 class]); NSLog(@"%@ %@ %@", [[block1 copy] class], [[block2 copy] class], [[block3 copy] class]); }
//打印
2019-01-11 14:14:06.902974+0800 MJ_TEST[2183:154918] __NSGlobalBlock__ __NSStackBlock__ __NSMallocBlock__ 2019-01-11 14:14:06.903260+0800 MJ_TEST[2183:154918] __NSGlobalBlock__ __NSMallocBlock__ __NSMallocBlock__ Program ended with exit code: 0
分析:
<1>只有stack类型block实例对象copy后的类型变为malloc,这个前面文章已经讨论过,没有问题;
<2>global类型实例对象存储在数据区,copy操作其实什么也没做;malloc在堆区,copy之后肯定还是在堆区,但不会开辟新的内存,只是引用计数加1——此处分析,可以通过clang和地址、引用计数打印来查看,此处不再赘述;
结论:
补充:上述copy的操作是针对block实例对象,那么类对象是存在哪个区呢?往下看
//代码
int a = 20; void test2() { int b = 10; void(^block1)(void) = ^{ NSLog(@"-----"); }; void(^block2)(void) = ^{ NSLog(@"-----%d", b); }; id block3 = [block2 copy]; id block1Cls = object_getClass(block1); id block2Cls = object_getClass(block2); id block3Cls = object_getClass(block3); NSLog(@"a--global--%p", &a); NSLog(@"b--auto place--%p", &b); NSLog(@"alloc----%p", [[NSObject alloc] init]); NSLog(@"Person----%p", [Person class]); NSLog(@"------block---instance---"); NSLog(@"block1----%@ %p", [block1 class], block1); NSLog(@"block2----%@ %p", [block2 class], block2); NSLog(@"block3----%@ %p", [block3 class], block3); NSLog(@"------block---Class---"); NSLog(@"block1Cls----%@ %p", block1Cls, block1Cls); NSLog(@"block2Cls----%@ %p", block2Cls, block2Cls); NSLog(@"block3Cls----%@ %p", block3Cls, block3Cls); }
//打印
2019-01-11 14:58:29.922125+0800 MJ_TEST[2443:177646] a--global--0x100002520 2019-01-11 14:58:29.922498+0800 MJ_TEST[2443:177646] b--auto place--0x7ffeefbff59c 2019-01-11 14:58:29.922525+0800 MJ_TEST[2443:177646] alloc----0x100526420 2019-01-11 14:58:29.922561+0800 MJ_TEST[2443:177646] Person----0x1000024f8 2019-01-11 14:58:29.922585+0800 MJ_TEST[2443:177646] ------block---instance--- 2019-01-11 14:58:29.922639+0800 MJ_TEST[2443:177646] block1----__NSGlobalBlock__ 0x1000020c0 2019-01-11 14:58:29.922666+0800 MJ_TEST[2443:177646] block2----__NSStackBlock__ 0x7ffeefbff560 2019-01-11 14:58:29.922699+0800 MJ_TEST[2443:177646] block3----__NSMallocBlock__ 0x102812000 2019-01-11 14:58:29.922717+0800 MJ_TEST[2443:177646] ------block---Class--- 2019-01-11 14:58:29.922736+0800 MJ_TEST[2443:177646] block1Cls----__NSGlobalBlock__ 0x7fffb33c3460 2019-01-11 14:58:29.922756+0800 MJ_TEST[2443:177646] block2Cls----__NSStackBlock__ 0x7fffb33c3060 2019-01-11 14:58:29.922777+0800 MJ_TEST[2443:177646] block3Cls----__NSMallocBlock__ 0x7fffb33c3160 Program ended with exit code: 0
分析:
<1>Person类对象:打印出的类对象Person的地址跟全局变量a和global