很常见的这个关于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가 아닌 블록은 힙이 아닌 스택에 배치되는데 이는 기본 유형과 동일합니다.
그러나 b는exampleB_addBlockToArray
의 블록 정의는int b = 1;
입니다. 배열에 저장되는 것은&b
과 같은 주소인 b에 대한 포인터입니다.0x1234567……
이 함수의 지역 변수입니다. 따라서 이 함수가 끝나면 사용된 메모리가 "해제됩니다". 실제로는 "데이터가 삭제되었으며 이 메모리를 사용할 수 있습니다"라고 표시됩니다.
실행되면 배열에 저장된exampleB_addBlockToArray
포인터는 여전히 존재하지만 포인터가 가리키는 메모리는 더 이상 이 포인터의 제어를 받지 않습니다. 다른 데이터가 이미 기록되어 있을 수도 있고, 방금 전까지의 데이터가 아직 남아 있을 수도 있습니다.
0x1234567……