4

我有一个类,它遍历 OSX 上给定文件夹的所有子文件夹,并为它找到的每个文件夹向其委托发送一条消息。

对于找到的每个文件夹,我想运行一个NSTask. 到目前为止,一切都很好。当我指定 aterminationHandlerNSTask,我遇到了问题。

这是代码:

-(void)crawler:(FTCFileSystemCrawler *)aCrawler
 didFindFolder:(NSURL *)aURL
      withName:(NSString *)aFileName
          stop:(BOOL *)stop{

    NSTask *task = [NSTask new];
    task.launchPath = @"/usr/bin/say";
    task.arguments = @[aFileName];
    task.terminationHandler = ^(NSTask *aTask){
        NSLog(@"Terminating!");
        [self.tasks removeObject:aTask];

    };
    [self.tasks addObject:task];

    [task launch];
    //[task waitUntilExit];


}

这工作正常,它发送launch到后NSTask,我发送waitUntilExit。如果我不这样做,则终止处理程序永远不会运行。

我究竟做错了什么?

PS请记住,这只是一个简单的例子。我实际上是在使用它来识别 git repos 并对其运行命令。

4

3 回答 3

2

尽管使用了这种方法,但您是否尝试过类似的操作task.terminationHandler = ^(NSTask *aTask),问题可能是在此块内使用未正确处理。

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(taskDidTerminate:)
                                             name:NSTaskDidTerminateNotification
                                           object:nil];
于 2013-10-08T11:14:36.943 回答
1

可能值得将其存储task到属性中,以便保留它并防止它在到达方法范围的末尾时被释放。例如,您的标头或私有接口中的以下内容:

@property (nonatomic, strong) NSTask *activeTask;

然后在你的方法结束时设置它:

self.activeTask = task;
于 2013-10-07T20:49:34.807 回答
1

NSTask一般来说,使用起来可能非常棘手,使用在其默认配置中不输出任何文本的工具更是如此。正如您所发现的,waitUntilExit它将解决您的问题,但它引发了另一个问题,因为它将阻塞直到任务完成。解决此问题的一种常见方法是使用NSPipe此答案 [此处] 中所见的 a。1虽然在 Cocoa 中有更好的方法来做到这一点!

使用 Cocoa API 作为语音引擎要比处理 aNSTask简单得多,NSSpeechSynthesizer. 这是您转换的相同代码的快速示例:

-(void)crawler:(FTCFileSystemCrawler *)aCrawler
 didFindFolder:(NSURL *)aURL
      withName:(NSString *)aFileName
          stop:(BOOL *)stop{

NSSpeechSynthesizer *speechSynth = [[NSSpeechSynthesizer alloc] initWithVoice:nil];
[speechSynth startSpeakingString:aFileName];

}

speechSynthesizer:didFinishSpeaking:更简单的是,如果在通话结束后仍需要回调,则可以使用委托方法。

于 2013-10-07T14:41:06.223 回答