对于 Mac OSX,我正在尝试使用 NSConnection 代理从一个应用程序实例到同一主机上的另一个应用程序实例的对象访问。相关代码如下。如果需要,我可以提供更多。假设当我说“服务器”时,我指的是实际使用 NSConnection 来“销售”对象的应用程序。而“客户端”是获得代理的同一应用程序的另一个实例。
一切正常,除了两个问题。
当充当服务器的应用程序试图拆除它正在出售的对象时,任何通过代理连接的客户端仍然存在。也就是说,即使在我调用
stopLocalServer
下面的函数之后,之前连接并获得代理对象的任何客户端应用程序仍然能够发送消息并调用服务器应用程序上的代码。我本来希望客户端在服务器调用后传递消息时抛出异常NSConnection:invalidate
。如何在不需要服务器进程退出的情况下强制断开任何客户端?在下面的
startClientConnection
代码中,如果服务器从一开始就没有使用预期的注册名称出售对象,那么客户端上的调用NSConnection:connectionWithRegisteredName:host
将立即返回 nil。这很好。但是,如果服务器通过startLocalServer
下面的代码开始出售一个对象,然后用 停止出售它stopLocalServer
,随后的客户端连接尝试将挂起(永远阻塞),直到服务器应用程序进程退出。对 NSConnection:connectionWithRegisteredName 的调用返回一个非零对象,但对 的调用[_clientConnection rootProxy]
将永远挂起,直到服务器应用程序实际退出。
我怀疑我没有正确地拆除原始的 NSConnection 对象,或者我在这里遗漏了一些基本的东西。
以下是我的用户界面代码所在平台的一些相关代码:
-(void)startLocalServer:(NSString*)str
{
[self stopLocalServer]; // clean up any previous instance that might be running
_serverConnection = [NSConnection new];
[_serverConnection setRootObject:self];
[_serverConnection registerName:str];
}
-(void)stopLocalServer
{
[_serverConnection registerName:nil];
[_serverConnection setRootObject:nil];
[_serverConnection invalidate];
_serverConnection = nil;
}
-(void)startClientConnection:(NSString*)str
{
[self stopClientConnection]; // tear down any previous connection
_clientConnection = [NSConnection connectionWithRegisteredName:str host:nil];
if ((_clientConnection == nil) || (_clientConnection.valid == NO))
{
LogEvent(@"ERROR - _clientConnection is nil or invalid!");
}
else
{
_proxy = [_clientConnection rootProxy];
}
}
-(void)stopClientConnection
{
_proxy = nil;
[_clientConnection invalidate];
_clientConnection = nil;
}