20

複数のコマンドを持つ PHP スクリプトがありsleep()ます。を使用してアプリケーションで実行したいと思いますNSTask。私のスクリプトは次のようになります。

echo "first\n"; sleep(1); echo "second\n"; sleep(1); echo "third\n";

通知を使用してタスクを非同期に実行できます。

- (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);
}

私の出力は(もちろん2秒後):

2011-08-03 20:45:19.474 MyApp[3737:903] first
second
third

私の質問は、印刷された直後にこれらの 3 つの単語を取得するにはどうすればよいですか?

4

2 に答える 2

23

NSFileHandle のwaitForDataInBackgroundAndNotifyメソッドを使用して、スクリプトが出力にデータを書き込んだときに通知を受け取ることができます。ただし、これは、インタープリターが文字列をすぐに送信する場合にのみ機能します。出力をバッファリングする場合、タスクの終了後に 1 つの通知を受け取ります。

- (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];
    NSFileHandle *fh = [p fileHandleForReading];
    [fh waitForDataInBackgroundAndNotify];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receivedData:) name:NSFileHandleDataAvailableNotification object:fh];

    [task launch];

}

- (void)receivedData:(NSNotification *)notif {
    NSFileHandle *fh = [notif object];
    NSData *data = [fh availableData];
    if (data.length > 0) { // if data is found, re-register for more data (and print)
        [fh waitForDataInBackgroundAndNotify];
        NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        NSLog(@"%@" ,str);
    }
}
于 2011-08-03T19:06:00.630 に答える