问题描述
很常见的这个关于block 的题
void exampleB_addBlockToArray(NSMutableArray *array) { char b = ’B’; [array addObject:^{ printf('%cn', b); }];}void exampleB() { NSMutableArray *array = [NSMutableArray array]; exampleB_addBlockToArray(array); void (^block)() = [array objectAtIndex:0]; block();}
Without ARC, the block is anNSStackBlockallocated on the stack ofexampleB_addBlockToArray(...). By the time it executes inexampleB(), the the block is no longer valid, because that stack has been cleared.
解释只说明了原理。我有一个理解不知道对不对?NSStackBlock 类似于一个栈“对象”,不像堆上的局部对象变量 在return 返回它,后所指的内容依然不会被释放。所以在函数结束后其实array 所存的对象(point)依然存在,只是所指的内存(内容)被释放掉了?
问题解答
回答1:尝试答一下,因为我对非 ARC 的情况不太有把握,不过我的理解跟你是一样的~
按照它的解释,非 ARC 的 block 是放在栈上而不是堆上的,那就是跟基础类型一样。在exampleB_addBlockToArray里那个 block 的定义就是int b = 1;这样,保存在数组里的是指向 b 的指针,也就是它的地址&b,也就是一个0x1234567……这样的东西。
但是 b 是exampleB_addBlockToArray这个函数的局部变量。所以在这个函数结束的时候,它用的那块儿内存就被『释放』掉了,实际上是标记为『数据已废弃,这块内存可以作为它用』了。
等到执行的时候,数组里存的那个指针0x1234567……还在,但是它指的那块内存早就不归这个指针管了。有可能是已经写上了别的数据,也有可能还残留着刚才的数据。