2010-04-27 103 views
1

我有一个包含两个组件的应用程序:用户与之交互的桌面应用程序以及可从桌面应用程序启用的后台进程。启用后台进程后,它将作为独立于桌面应用的用户启动代理运行。在Mac OS X上停止后台进程的正确方法是什么?

但是,我想知道的是当用户禁用后台进程时该怎么办。此时我想停止后台进程,但我不确定最佳方法是什么。我看到的3个选项是:

  1. 使用'kill'命令。
    • 直接,但不可靠,只是似乎有点“错误”。
  2. 使用NSMachPort将桌面应用程序的退出请求发送到后台进程。
    • 这是我想到的最好的方法,但我遇到了一个实现问题(我将在一个单独的查询中发布这个问题),我想确保这个方法在进行之前是正确的进一步。
  3. 别的什么?

非常感谢您提供任何帮助/见解。

+0

hooray让程序让用户关闭(有时)不需要的后台进程! – 2010-04-27 19:17:30

+0

在发布查询之前,我想出了我的NSMachPort的实现问题。事实证明,NSMachBootstrapServer不喜欢注册使用特定端口号初始化的端口。当我使用默认的初始化调用时,一切正常。 – mcsheffrey 2010-04-27 19:23:27

回答

0

守护进程可以处理退出苹果事件或在CFMessagePort上侦听。

如果你使用信号,你应该处理信号,可能是SIG_QUIT,而不是让系统杀死你的进程。

如果您有可能需要一段时间的清理,请使用信号以外的其他东西。如果你基本上只是调用退出,那么信号是好的。

如果你已经有一个CFRunLoop去使用CFMessagePort。如果你已经处理苹果事件,而不是处理退出。

CFMessagePort是CFMachPort的一个包装,提供了一个名称和一些其他的便利。你也可以使用NS包装。

+0

谢谢!由于我有NSRunLoop,我会坚持使用NSMachPort。我研究了NSMessagePort,但目前的Apple documentation告诉开发人员避免将其用于支持NSMachPort,并且可能很快就会被弃用。 – mcsheffrey 2010-04-27 19:40:34

+0

谢谢!由于我有NSRunLoop,我会坚持使用NSMachPort。我研究了NSMessagePort,但目前的Apple [文档](http://developer.apple.com/mac/library/documentation/cocoa/reference/Foundation/Classes/NSMessagePort_Class/Reference/Reference.html)告诉开发人员避免使用它赞成NSMachPort,并且它很快就会被弃用。 – mcsheffrey 2010-04-27 19:43:42

0

我发现一个更简单的方法来使用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 

要设置监听器,后台进程只是简单的分配和inits的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是为需要解决的情况创建基本通信渠道的最简单方式。

相关问题