objective-c - 异步执行 shell 命令无法正常工作

标签 objective-c cocoa asynchronous nstask nsfilehandle

所以,这是我的代码:

- (void)runCmd:(NSString *)cmd withArgs:(NSArray *)args
{
    NSLog(@"\nRunning ::\n\tCmd : %@\n\tArgs : %@",cmd, args);
    [theSpinner start];
    if (task)
    {
        [task interrupt];

    }
    else
    {
        task = [[NSTask alloc] init];
        [task setLaunchPath:cmd];

        [task setArguments:args];

        [pipe release];

        pipe = [[NSPipe alloc] init];
        [task setStandardOutput:pipe];

        NSFileHandle* fh = [pipe fileHandleForReading];

        NSNotificationCenter* nc;

        nc = [NSNotificationCenter defaultCenter];
        [nc removeObserver:self];
        [nc addObserver:self 
               selector:@selector(dataReady:) 
                   name:NSFileHandleReadCompletionNotification 
                 object:fh];
        [nc addObserver:self selector:@selector(dataAvailable:) name:NSFileHandleDataAvailableNotification object:fh];
        [nc addObserver:self 
               selector:@selector(taskTerminated:) 
                   name:NSTaskDidTerminateNotification 
                 object:task];

        [task launch];
        [fh readInBackgroundAndNotify];
    }
}

- (void)dataAvailable:(NSNotification*)n
{
    NSLog(@"Data Available : %@",n);
}

- (void)dataReady:(NSNotification*)n
{
    NSData* d;

    d = [[n userInfo] valueForKey:NSFileHandleNotificationDataItem];

    NSLog(@"Data Ready : %@",n);

    if ([d length])
    {
        NSLog(@"Data Ready : %@",[[NSString alloc] initWithData:d encoding:NSUTF8StringEncoding]);
    }
}

- (void) taskTerminated:(NSNotification*)note
{
    NSLog(@"Task Terminated : %@",note);
    [task release];
    task = nil;
    [theSpinner stop];

    NSAlert *alert = [[[NSAlert alloc] init] autorelease];
    [alert setMessageText:[NSString stringWithFormat:@"Command finished"]];

    [alert runModal];
}

我尝试运行带有参数(例如要由 php test.php 解释的文件)的命令(例如 /usr/bin/php 中的 php 解释器) >).

事情是:

  • 脚本运行良好
  • 但是,我收到了数据就绪任务终止 在我设法获得所有输出之前通知。 (我是说, dataReady: 函数仅获取
    的第一部分 输出,其余部分无处可寻...)

我基本上想在命令运行时异步读取所有输出。

有什么想法吗?我做错了什么?

谢谢!

最佳答案

您可以使用readInBackgroundAndNotify来安排您的阅读。此方法仅读取一个充满数据的缓冲区并发出通知。您需要在通知方法中再次调用 readInBackgroundAndNotify 来读取更多数据,或者如果您想一次接收所有数据,则需要使用 readToEndOfFileInBackgroundAndNotify

关于objective-c - 异步执行 shell 命令无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9965360/

相关文章:

ios - 设置两个动态标签之间的距离

ios - CBLLiveQuery 与 kCBLDocumentChangeNotification

ios 自动布局视觉格式 - 对齐

iphone - iOS5 上的 CCKeyDerivationPBKDF

iphone - 我如何获得当前日期?

objective-c - CoreData 应用程序退出时间过长

c# - 如何延长使用耐用品的azure功能的超时?

c# - 使用 ExecuteNonQueryAsync 和报告进度

Java异步调用用于目标输出的方法

iphone - 如何计算等轴测图上两点之间的实际距离?