以下是说明问题的代码段
__weak id ptr = nil;
__weak id ptr2 = nil;
@autoreleasepool {
void (^block)(void) = [^{
NSLog(@"hahaha");
} copy];
block();
[[(id)block rac_willDeallocSignal] subscribeCompleted:^{
NSLog(@"block will dealloc");
}];
ptr = block;
int blockRetainCount = CFGetRetainCount((__bridge CFTypeRef)block);
NSObject *obj = [[NSObject alloc] init];
[obj.rac_willDeallocSignal subscribeCompleted:^{
NSLog(@"Obj dealloc");
}];
ptr2 = obj;
int objRetainCount = CFGetRetainCount((__bridge CFTypeRef)obj);
NSLog(@"oK");
}
NSLog(@"after pool %@ %@" , ptr, ptr2);
当我运行此代码段时,我会看到Obj dealloc
打印到控制台但不是block will dealloc
。在自动释放池之后,我将看到ptr
仍然包含对块的有效refence,而ptr2
已按预期正确重置为nil。为什么会出现这种差异?块什么时候才能完全被释放?
答案 0 :(得分:3)
多个问题应该说服你不要尝试这样的事情:
一,CFGetRetainCount不保证在ARC存在的情况下返回任何有意义的内容。
二,无法保证块完全使用保留计数。不捕获任何变量的块被分配为静态变量;复制,保留等等对它们一无所知,它们永远不会被分配或取消分配。
第三,不能保证任何块在解除分配时都会调用dealloc。并且无法保证它会在下一个OS或iOS版本中发生。