【问题标题】:Passing extra data to NSTask output handler将额外数据传递给 NSTask 输出处理程序
【发布时间】:2015-02-18 20:51:19
【问题描述】:

我需要读取 NSTask 的输出。这篇文章中的代码实现了这一点:How to receive output of NSTask in Cocoa?。但是,我想向这个函数传递额外的数据。我试图创建一个字典并通过选择器将其传递,但​​这没有用。

NSDictionary *dict = [[NSDictionary alloc] initWithObjectsAndKeys:completion_, @"a", [outputPipe fileHandleForReading], @"b", nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(readCompleted:) name:NSFileHandleReadToEndOfFileCompletionNotification object:dict];

有什么想法吗?

【问题讨论】:

    标签: macos nsnotificationcenter nstask nsnotification


    【解决方案1】:

    首先,-addObserver:selector:name:object:object: 参数是发布通知的对象。如果指定名称的通知由不同的对象发布,通知中心不会调用您的选择器。由于您的字典永远不会发布NSFileHandleReadToEndOfFileCompletionNotification(因为字典不会发布通知),因此您的选择器将永远不会被调用。

    所以,不要将字典作为object 传递。它不会像你想的那样做。这不是将信息传递给观察方法的方法。

    您可以使用更现代的基于块的观察者方法来执行此操作:

    __block id observation = [[NSNotificationCenter defaultCenter] addObserverForName:NSFileHandleReadToEndOfFileCompletionNotification
                                                                               object:[outputPipe fileHandleForReading]
                                                                                queue:nil
                                                                           usingBlock:^(NSNotification *note) {
                                                                               // Do whatever you want to do in response to the notification here.
                                                                               // You can access the completion_ variable directly.
                                                                               [[NSNotificationCenter defaultCenter] removeObserver:observation];
                                                                               observation = nil;
                                                                           }];
    

    在通知触发之前,您必须小心保持观察对象处于活动状态,但一旦触发就将其移除并释放(通过清除强引用)。我已经在上面展示了。

    【讨论】:

      【解决方案2】:

      这是获取任务输出的异步解决方案。

      task.standardOutput = [NSPipe pipe];
      [[task.standardOutput fileHandleForReading] setReadabilityHandler:^(NSFileHandle *file) {
      NSData *data = [file availableData]; // this will read to EOF, so call only once
      NSLog(@"Task output! %@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
      
      // if you're collecting the whole output of a task, you may store it on a property
      //[self.taskOutput appendData:data];
      

      }];

      【讨论】:

        猜你喜欢
        • 2021-05-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-09-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多