Nous devons capturer stdout dans iOS parce que nous utilisons un projet open source qui communique via stdin/stdoutImpossible d'obtenir NSFileHandleDataAvailableNotification au feu pour les tuyaux stdout
Cela fonctionne:
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);
La console imprime:
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!
Cependant, l'exemple ci-dessus est bloqué. Pourquoi le code asynchrone suivant ne fonctionne-t-il pas?
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];
Le bloc de code de notification ne semble pas être appelé - la console ne émet
Qu'est-ce que le programme ne après avoir écrit la chaîne? Est-ce qu'il renvoie la boucle d'exécution? –
Le code est dans une méthode qui est exécutée lorsqu'un bouton d'interface utilisateur est sélectionné. Je suis gêné de dire que je ne sais pas ce qu'est une boucle de course - pouvez-vous élaborer? – Lightbeard
[L'explication d'Apple sur les boucles d'exécution.] (Https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html) La boucle d'événement principale d'une application est construite au-dessus de une boucle d'exécution, donc il semble que vous êtes probablement bon à cet égard. Je l'ai soulevé parce que les documents pour '-waitForDataInBackgroundAndNotify' disent" Vous devez appeler cette méthode à partir d'un thread qui a une boucle d'exécution active. " Si vous aviez, par exemple, bloqué en attendant la notification, cela n'aurait pas fonctionné. –