Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 什么';在Mac OS X上停止后台进程的正确方法是什么?_Objective C_Daemon_User Agent - Fatal编程技术网

Objective c 什么';在Mac OS X上停止后台进程的正确方法是什么?

Objective c 什么';在Mac OS X上停止后台进程的正确方法是什么?,objective-c,daemon,user-agent,Objective C,Daemon,User Agent,我有一个包含两个组件的应用程序:一个与用户交互的桌面应用程序,以及一个可以从桌面应用程序启用的后台进程。启用后台进程后,它将作为独立于桌面应用程序的用户启动代理运行 然而,我想知道的是当用户禁用后台进程时该怎么做。在这一点上,我想停止后台进程,但我不确定最好的方法是什么。我看到的3个选项是: 使用“kill”命令。 直接,但不可靠,只是看起来有点“错误”。 使用NSMachPort将退出请求从桌面应用发送到后台进程。 这是我想到的最好的方法,但我遇到了一个实现问题(我将在另一个查询中发布此问题

我有一个包含两个组件的应用程序:一个与用户交互的桌面应用程序,以及一个可以从桌面应用程序启用的后台进程。启用后台进程后,它将作为独立于桌面应用程序的用户启动代理运行

然而,我想知道的是当用户禁用后台进程时该怎么做。在这一点上,我想停止后台进程,但我不确定最好的方法是什么。我看到的3个选项是:

  • 使用“kill”命令。 直接,但不可靠,只是看起来有点“错误”。
  • 使用NSMachPort将退出请求从桌面应用发送到后台进程。
    • 这是我想到的最好的方法,但我遇到了一个实现问题(我将在另一个查询中发布此问题),我希望在进一步讨论之前确保该方法是正确的。
  • 还有别的吗

  • 提前感谢您提供的任何帮助/见解。

    守护进程可以处理退出apple事件或侦听CFMessagePort

    如果您使用信号,您应该处理发送的信号,可能是SIG_QUIT,而不是让系统终止您的进程

    如果清理可能需要一段时间,请使用信号以外的方法。如果您基本上只是在呼叫退出,那么信号就可以了

    如果您已经有了一个CFRunLoop,那么使用CFMessagePort。如果您已经在处理apple事件,请停止处理


    CFMessagePort是一个围绕CFMachPort的包装器,它提供了一个名称和一些其他便利。您也可以将NS包装器用于其中之一。

    我发现了一种更简单的方法,可以使用NSConnection对象来实现这一点。我使用以下标题创建了一个非常简单的ExitListener对象:

    @interface ExitListener : NSObject {
        BOOL _exitRequested;
        NSConnection *_connection;
    }
    
    @property (nonatomic, assign) BOOL exitRequested;
    
    - (void)requestExit;
    
    @end
    
    这一实施:

    @implementation ExitListener
    
    @synthesize exitRequested = _exitRequested;
    
    // On init we set ourselves up to listen for an exit
    - (id)init {
        if ((self = [super init]) != nil) {
            _connection = [[NSConnection alloc] init];
    
            [_connection setRootObject:self];
            [_connection registerName:@"com.blahblah.exitport"];
        }
        return self;
    }
    
    - (void)dealloc {
        [_connection release];
    
        [super dealloc];
    }
    
    - (void)requestExit {
        [self setExitRequested:YES];
    }
    
    @end
    
    要设置侦听器,后台进程只需分配并初始化ExitListener的一个实例。然后,桌面应用程序通过以下调用请求后台进程退出:

    - (void)stopBackgroundProcess {
        // Get a connection to the background process and ask it to exit
        NSConnection *connection = [NSConnection connectionWithRegisteredName:@"com.blahblah.exitport" host:nil];
        NSProxy *proxy = [connection rootProxy];
        if ([proxy respondsToSelector:@selector(requestExit)]) {
            [proxy performSelector:@selector(requestExit)];
        }
    }
    

    直接使用NSMachPorts似乎会在注册和获取引用方面带来更多的问题。我发现NSConnection是为我需要解决的那种情况创建基本通信通道的最简单方法。

    让用户关闭(有时)不需要的后台进程的程序万岁!在发布查询之前,我解决了NSMachPort的实现问题。事实证明,NSMachBootstrapServer不喜欢注册使用特定端口号初始化的端口。当我使用默认的init调用时,一切正常。谢谢!因为我有一个nsrunlop,所以我将坚持使用NSMachPort。我查看了NSMessagePort,但当前的Apple>告诉开发者避免使用它,而支持NSMachPort,并且它可能很快就会被弃用。谢谢!因为我有一个nsrunlop,所以我将坚持使用NSMachPort。我查看了NSMessagePort,但当前的苹果公司告诉开发人员不要使用它,而是支持NSMachPort,而且它可能很快就会被弃用。