[NSStream scheduleInRunLoop:forMode:]是否保留NSStream?

时间:2016-10-05 14:38:59

标签: reference retain nsstream nsrunloop

我想使用nsstreams发送和接收一些数据。我不想让我的代码混乱,所以我想知道:

我是否需要保留对NSStream的强引用,或者[NSStream scheduleInRunLoop:forMode:]是否创建了对它的强引用?

我找不到任何相关文档。我已经尝试了,它没有自己的强大参考。

我希望有人可以证实或反驳这一发现。

1 个答案:

答案 0 :(得分:2)

是的,在RunLoop中安排NSStream后,其引用计数会增加。我认为这段代码足以证明它:

NSInputStream* nStream = [[NSInputStream alloc] initWithFileAtPath:path];
NSLog(@"Stream retain count A is %ld", CFGetRetainCount((__bridge CFTypeRef)nStream));
NSValue* val = [NSNumber valueWithPointer:(__bridge const void * _Nullable)(nStream)];// not increment reference counter
NSLog(@"Stream retain count B is %ld", CFGetRetainCount(val.pointerValue));
[nStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
NSLog(@"Stream retain count C is %ld", CFGetRetainCount(val.pointerValue));
nStream = nil;
NSLog(@"Stream retain count D is %ld", CFGetRetainCount(val.pointerValue));

和控制台输出:

 Stream retain count A is 1
 Stream retain count B is 1
 Stream retain count C is 3
 Stream retain count D is 2

因此,添加到NSRunLoop会使数字引用增加2.在原始强引用计数器值无效后仍然为正,这样可以防止对象的重新分配。

因为对象仍然存在,将响应此代码:

[(__bridge const NSInputStream*)val.pointerValue open];
[(__bridge const NSInputStream*)val.pointerValue close];

但下一行会导致崩溃 - 现在流已从NSRunLoop中删除。所有对它的引用都被删除了 - 剩下的是指针的值 - 现在是deallocated - object(行为类似于assigned指针)。调用已解除分配的对象始终意味着EXC_BAD_ACCESS ...

NSLog(@"Stream retain count E is %ld",
CFGetRetainCount(val.pointerValue));//crash here