2015-10-04 59 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線程運行的,而不是後臺線程。

(發佈萬一有人是懶惰和我一樣,並不想通過評論來分析去尋找答案..)