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