无法仅在currentRunLoop上安排NSStream MainRunLoop

时间:2014-08-05 20:46:08

标签: ios objective-c nsrunloop

我正在尝试在并发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
 }

2 个答案:

答案 0 :(得分:2)

确保您计划启用流的运行循环实际运行,并以您已安排流的模式运行。如果运行循环没有运行,您的流也不会做任何事情。

答案 1 :(得分:0)

首先,在主runloop上安排流是不好的 - 特别是在标准模式下。

在这种设置情况下,保持菜单打开,或在桌面上拖动文件的事件,或者实际上任何冗长的UI事件处理,都会暂时阻止runloop模式并使您的流饿死。

您确实应该使用辅助线程来处理流。我现在正在尝试做一些与你类似的事情 - 从NSOperation处理我的流(它总是运行在一些未知的线程的上下文中),但我在Apple的#34中找到了令人沮丧的段落;流编程指南"

  

在打开流以开始数据流之前,请发送一个   scheduleInRunLoop:forMode:消息到流对象以计划它   在运行循环上接收流事件。通过这样做,你正在帮助   代理在流上没有数据时避免阻塞   读。如果正在另一个线程上进行流式传输,请务必   在该线程的运行循环上安排流对象。 你永远不应该   尝试从不同于的线程访问计划的流   一个拥有流的运行循环。最后,发送NSInputStream   实例一个打开的消息,用于启动输入中的数据流   源。

现在在当前操作的线程runloop上重新安排流,并运行它......似乎是一个巨大的开销,我不确定NSStream是否可以过于频繁地处理重新安排。

我不知道最好做些什么,但我正在测试和学习,并会尽快更新。

当然,您可以为流创建一个特殊线程,并从您的操作中 - 同步调用该线程对流的所有访问权。