2015-10-04 30 views
1

我们需要,因为我们使用的是通过stdin通信的开源项目能把握标准输出中的iOS /标准输出无法获得NSFileHandleDataAvailableNotification火标准输出管道

这工作:

NSPipe *pipe = [NSPipe pipe]; 
NSFileHandle *readh = [pipe fileHandleForReading]; 

dup2([[pipe fileHandleForWriting] fileDescriptor], fileno(stdout)); 

[@"Hello iOS World!" writeToFile:@"/dev/stdout" atomically:NO encoding:NSUTF8StringEncoding error:nil]; 

NSData *data = [readh availableData]; 
NSLog(@"%d", [data length]); 
NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 
NSLog(@"%@%@", @"stdout captured:", str); 

控制台打印:

2015-10-04 12:03:29.396 OpeningExplorer[857:42006] 16 
2015-10-04 12:03:29.397 OpeningExplorer[857:42006] stdout captured:Hello iOS World! 

但是,上面的示例块。为什么下面的异步代码不起作用?

NSPipe *pipe = [NSPipe pipe]; 
    NSFileHandle *readh = [pipe fileHandleForReading]; 

    dup2([[pipe fileHandleForWriting] fileDescriptor], fileno(stdout)); 

    [[NSNotificationCenter defaultCenter] addObserverForName:NSFileHandleDataAvailableNotification 
                 object:readh 
                 queue:[NSOperationQueue mainQueue] 
                usingBlock:^(NSNotification *note) { 
     NSFileHandle *fileHandle = (NSFileHandle*) [note object]; 
     NSLog(@"inside listener"); 
     NSData *data = [fileHandle availableData]; 
     NSLog(@"%d", [data length]); 
     NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 
     NSLog(@"%@%@", @"stdout captured:", str); 

    }]; 
    [readh waitForDataInBackgroundAndNotify]; 

    [@"Hello iOS World!" writeToFile:@"/dev/stdout" atomically:NO encoding:NSUTF8StringEncoding error:nil]; 

通知代码块似乎并没有被称为 - 控制台不上waitForDataInBackgroundAndNotify输出任何东西

+1

是什么程序写入字符串后做什么?它是否返回运行循环? –

+0

代码位于选择UI按钮时运行的方法中。我很尴尬地说我不知道​​运行循环是什么 - 你能详细说明吗? – Lightbeard

+2

[Apple对运行循环的解释](https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html)应用程序的主要事件循环建立在一个运行循环,所以这听起来像你可能在这方面很好。我提起它是因为'-waitForDataInBackgroundAndNotify'的文档说“你必须从一个具有活动运行循环的线程调用这个方法。”例如,如果您在等待通知时被阻止,那就不会奏效。 –

回答

0

Apple's documentation:“你必须从具有积极的运行循环线程调用此方法“。

这意味着你不能在NSOperationQueueNSThread内调用此函数。因此,请确保此代码是从主UI线程运行的,而不是后台线程。

(发布万一有人是懒惰和我一样,并不想通过评论来分析去寻找答案..)