很常见的这个关于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)依然存在,只是所指的内存(内容)被释放掉了?
Essayez de répondre, car je ne suis pas sûr de la situation non-ARC, mais ma compréhension est la même que la vôtre~
Selon son explication, les blocs non-ARC sont placés sur la pile au lieu du tas, ce qui est le même que le type de base. La définition du bloc dans
exampleB_addBlockToArray
estint b = 1;
. Ce qui est enregistré dans le tableau est le pointeur vers b, qui est son adresse&b
, qui ressemble à0x1234567……
.Mais b est
exampleB_addBlockToArray
une variable locale de cette fonction. Ainsi, lorsque cette fonction se termine, la mémoire qu'elle a utilisée est "libérée". En fait, elle est marquée comme "les données ont été supprimées et cette mémoire peut être utilisée pour cela".Une fois exécuté, le pointeur
0x1234567……
stocké dans le tableau est toujours là, mais la mémoire vers laquelle il pointe n'est plus sous le contrôle de ce pointeur. Il se peut que d'autres données aient déjà été écrites, ou qu'il existe encore des données datant de maintenant.