我遇到以下情况,我创建了一个 GCD 调度队列,并在其中安排了一个NSStream
到目前的NSRunLoop
,按照其规范要求它发出委托事件,然后我使用该线程运行运行循环[[NSRunLoop currentRunLoop run]
.
这会产生三种可能的情况:
创建一个串行队列,其中通过流发送初始写入消息,并且仅当存在来自该流的委托回调时才发送其他写入消息NSStream
对象,因为尝试在不遵守此模式的情况下写入新消息(这是理想的)将失败,因为队列被运行循环锁定。
创建一个并发队列,可以在其中自由地将消息写入流,因为发送到队列的块将与运行运行循环的块同时执行。然而,虽然希望使写入消息和运行循环并发运行,但肯定不希望阻塞同时运行的队列尝试同时写入流。
创建两个队列——一个负责保持运行循环活动并接收从流读取的回调,另一个负责向流发送异步写入消息。这看起来很理想,但似乎NSStream
文档明确指出,不应尝试在调度的线程之外读取/写入流。
鉴于这些场景都不理想,如何解决这些问题?
迟到了,但您可以直接使用以下命令为流设置所需的调度队列,而不是使用运行循环
void CFReadStreamSetDispatchQueue(CFReadStreamRef stream, dispatch_queue_t q);
void CFWriteStreamSetDispatchQueue(CFWriteStreamRef stream, dispatch_queue_t q);
其中CFReadStreamRef可以采用桥接的NSInputStream,CFWriteStreamRef可以采用桥接的NSOutputStream。这样,您根本不必安排或取消安排运行循环,并且您的流将在后台运行。
摘录自此苹果示例代码 https://developer.apple.com/library/content/samplecode/sc1236/Listings/TLSTool_TLSToolCommon_m.html:
CFReadStreamSetDispatchQueue((__bridge CFReadStreamRef) self.inputStream, self.queue);
CFWriteStreamSetDispatchQueue((__bridge CFWriteStreamRef) self.outputStream, self.queue);
在 Swift 中,你可以直接调用函数:
CFReadStreamSetDispatchQueue(inputStream, streamQueue)
CFWriteStreamSetDispatchQueue(outputStream, streamQueue)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)