NSTask 和 NSTaskDidTerminateNotification 令人沮丧的问题

Posted

技术标签:

【中文标题】NSTask 和 NSTaskDidTerminateNotification 令人沮丧的问题【英文标题】:Frustrating issue with NSTask and NSTaskDidTerminateNotification 【发布时间】:2013-07-12 00:23:09 【问题描述】:

因此,我在这个问题上搜索了几天。最后,我正处于被卡住的地步。我已经阅读了 Threading 编程指南,并在它谈到 NSRunLoops 时密切关注它,我认为这可能是我想要的方向。问题来了:

我有一个非常简单的演示项目,它只包含一个 AppDelegate 和一个名为 TestObj 的类,在 testObj 中我有

@implementation TestObj

-(void)executeTheTaskWithObj:(id)sender 

NSTask *task = [[NSTask alloc] init];
[task setLaunchPath: @"/bin/sh"];
NSArray *arguments = [NSArray arrayWithObjects: @"-c", @"echo hello", nil];
[task setArguments:arguments];

    /* This works but I want to handle the notification in this class, not the senders     class */
//[[NSNotificationCenter defaultCenter] addObserver:sender    selector:@selector(taskComplete:) name:NSTaskDidTerminateNotification object:task];

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(taskComplete:) name:NSTaskDidTerminateNotification object:task];
[task launch];


-(void)taskComplete:(NSNotification *)notification 
NSLog(@"Task Complete");

我的 appDelegate 像这样调用这个类

@implementation AppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification 
TestObj *myObj = [[TestObj alloc] init];
[myObj executeTheTaskWithObj:self];

所以问题是应用程序因“objc_msgSend()”而崩溃断点证明,只要我将“self”添加为观察者,它就会崩溃。无论如何,我故意没有多线程,这只是一个正常的调用。所以我的第一个预感可能是我应该使用 NSRunLoop 的一个实例。所以我阅读了线程编程指南的 NSRunLoop 部分,它明确指出可可应用程序在 main 中自动启动了一个 runloop。所以我不应该再创造一个吧?我不想回答这个问题,但至少有一些关于如何解决这个问题的指导。谢谢!

【问题讨论】:

如果您在回溯后发生崩溃。 对不起,我不应该说崩溃。我的意思是它处于暂停状态。调试器只给出线程 1:EXC_BAD_ACCESS(code 13, address=0x0)。我已经移动了断点,如果我在 [task launch] 之后立即设置断点并且它输出“hello”但之后立即暂停,我可以让任务执行。我认为的问题是我的 testObj 在收到通知之前正在被释放。它一定是我想念的小东西。 访问不正确会导致崩溃。 这不应该适用于 OS X 吗? NSTask 不适用于 ios 【参考方案1】:

问题是 myObj 在 applicationDidFinishLaunching 超出范围后被释放。创建一个强大的属性 myObj,然后它应该可以正常工作。

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification 
    self.myObj = [[TestObj alloc] init];
    [self.myObj executeTheTaskWithObj:self];

【讨论】:

以上是关于NSTask 和 NSTaskDidTerminateNotification 令人沮丧的问题的主要内容,如果未能解决你的问题,请参考以下文章

如何在主线程上安全地使用[NSTask waitUntilExit]?

使用包含文件的第一级文件夹的 NSTask 创建 zip 存档

NSTask 启动路径错误 [重复]

NSTask 源码中有趣的地方

将授权服务与 NSTask 一起使用

NSBundle 中的 NSTask