我正在尝试在并发NSOperation中使用NSInputStream。
我注意到我无法在当前的运行循环上安排它,只有主运行循环。 为什么是这样?我是否需要为NSOperation所在的线程创建自己的运行循环?
以下是代码:
{
NSURL *filePath = [Utils getFullFileURLFromFileId:self.fileId];
NSString *filePathString = [filePath path];
self.iStream = [[NSInputStream alloc] initWithFileAtPath:filePathString];
self.iStream.delegate = self;
[self.iStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
[self.iStream open];
}
#pragma mark - NSStreamDelegate
- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
{
// do stuff
}
答案 0 :(得分:2)
确保您计划启用流的运行循环实际运行,并以您已安排流的模式运行。如果运行循环没有运行,您的流也不会做任何事情。
答案 1 :(得分:0)
首先,在主runloop上安排流是不好的 - 特别是在标准模式下。
在这种设置情况下,保持菜单打开,或在桌面上拖动文件的事件,或者实际上任何冗长的UI事件处理,都会暂时阻止runloop模式并使您的流饿死。
您确实应该使用辅助线程来处理流。我现在正在尝试做一些与你类似的事情 - 从NSOperation处理我的流(它总是运行在一些未知的线程的上下文中),但我在Apple的#34中找到了令人沮丧的段落;流编程指南"
在打开流以开始数据流之前,请发送一个 scheduleInRunLoop:forMode:消息到流对象以计划它 在运行循环上接收流事件。通过这样做,你正在帮助 代理在流上没有数据时避免阻塞 读。如果正在另一个线程上进行流式传输,请务必 在该线程的运行循环上安排流对象。 你永远不应该 尝试从不同于的线程访问计划的流 一个拥有流的运行循环。最后,发送NSInputStream 实例一个打开的消息,用于启动输入中的数据流 源。
现在在当前操作的线程runloop上重新安排流,并运行它......似乎是一个巨大的开销,我不确定NSStream是否可以过于频繁地处理重新安排。
我不知道最好做些什么,但我正在测试和学习,并会尽快更新。
当然,您可以为流创建一个特殊线程,并从您的操作中 - 同步调用该线程对流的所有访问权。