NSTask die Echtzeit-Ausgabe
Ich habe ein PHP-Skript, welches mehrere sleep()
Befehle. Ich möchte, um es auszuführen in meiner Anwendung mit NSTask
. Mein Skript sieht wie folgt aus:
echo "first\n"; sleep(1); echo "second\n"; sleep(1); echo "third\n";
Ich ausführen kann, meine Aufgabe asynchron mit Benachrichtigungen:
- (void)awakeFromNib {
NSTask *task = [[NSTask alloc] init];
[task setLaunchPath: @"/usr/bin/php"];
NSArray *arguments;
arguments = [NSArray arrayWithObjects: @"-r", @"echo \"first\n\"; sleep(1); echo \"second\n\"; sleep(1); echo \"third\n\";", nil];
[task setArguments: arguments];
NSPipe *p = [NSPipe pipe];
[task setStandardOutput:p];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(taskExited:) name:NSTaskDidTerminateNotification object:task];
[task launch];
}
- (void)taskExited:(NSNotification *)notif {
NSTask *task = [notif object];
NSData *data = [[[task standardOutput] fileHandleForReading] readDataToEndOfFile];
NSString *str = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
NSLog(@"%@",str);
}
Meiner Ausgabe (nach 2 Sekunden, natürlich):
2011-08-03 20:45:19.474 MyApp[3737:903] first
second
third
Meine Frage ist: wie bekomme ich diese drei Worte sofort, nachdem Sie gedruckt sind?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Können Sie NSFileHandle ist
waitForDataInBackgroundAndNotify
Methode, um eine Benachrichtigung zu erhalten, wenn das Skript schreibt Daten an Ihrem Ausgang. Diese funktionieren aber nur, wenn der interpreter sendet die Saiten sofort. Wenn es Puffer Ausgabe, erhalten Sie eine Meldung auf, nachdem die Aufgabe beendet.readInBackgroundAndNotify
im-receiveData
. Danke für die Idee!waitForDataInBackgroundAndNotify
, nichtreadInBackgroundAndNotify
.find
Befehl erzeugt lange Ergebnis und das snippet benötigt eine zusätzliche[fh waitForDataInBackgroundAndNotify]
um die kompletten Daten. Hoffe, das hilft Anfänger wie mich.Referenz, hier ist ughoavgfhw Antwort in swift.
Dieses Konstrukt wird notwendig sein, wenn Ihre Aufgabe produziert viele Ausgabe in die pipe. Einfach anrufen
pipe.fileHandleForReading.readDataToEndOfFile()
wird nicht funktionieren, weil die Aufgabe ist das warten auf das Rohr zu entleeren, so kann es schreiben mehr, während das Programm wartet auf das Ende der Daten. So wird Ihr Programm hängen. Diese Benachrichtigung-und Beobachter-Konstrukt erlaubt die pipe gelesen werden asynchron und verhindert so, dass die oben erwähnten Patt.