reference - [NSStream scheduleInRunLoop : forMode:] retain the NSStream? 是否

标签 reference retain nsstream nsrunloop

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

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

我找不到任何相关文档。我已经尝试过了,它在没有自己的强引用的情况下也能工作。

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

最佳答案

是的,在 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 中删除。对它的所有引用都已删除 - 剩下的是指针的值 - 现在已释放 - 对象(行为类似于 assigned pointer)。调用释放对象总是意味着 EXC_BAD_ACCESS...

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

关于reference - [NSStream scheduleInRunLoop : forMode:] retain the NSStream? 是否,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39876974/

相关文章:

ios - 如何在另一个线程上正确打开和关闭 NSStream

objective-c - NSInputStream 不调用委托(delegate)(流 :handleEvent:)

ios - 我如何在 obj-c 的 block 中通过引用发送参数

c++ - 何时使用引用与指针

iphone - retain setter 是如何用@synthesize 实现的?

ios - UIDocument 从不调用 dealloc

objective-c - performSelector:withObject: 及其保留行为

sockets - 如何测试我的远程套接字 NSStream 是否正确打开

MySQL 主键声明

reference - 关于在 pthreads 中使用 OpenSSL 的教程