Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/10.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 N连接-如何正确地进行“连接”;“不变的”;物体的形状?_Objective C_Macos_Distributed Objects_Nsconnection - Fatal编程技术网

Objective c N连接-如何正确地进行“连接”;“不变的”;物体的形状?

Objective c N连接-如何正确地进行“连接”;“不变的”;物体的形状?,objective-c,macos,distributed-objects,nsconnection,Objective C,Macos,Distributed Objects,Nsconnection,对于MacOSX,我尝试使用NSConnection代理同一主机上从一个应用程序实例到另一个应用程序实例的对象访问。相关代码如下。如果需要,我可以提供更多。假设当我说“服务器”时,我指的是实际“出售”具有NSConnection的对象的应用程序。“客户机”是同一应用程序的另一个实例,它向该应用程序获取代理 除了两个问题外,一切正常 当充当服务器的应用程序试图拆除它正在出售的对象时,通过代理连接的任何客户端仍然保留。也就是说,即使在我调用下面的stopLocalServer函数之后,以前连接并获得

对于MacOSX,我尝试使用NSConnection代理同一主机上从一个应用程序实例到另一个应用程序实例的对象访问。相关代码如下。如果需要,我可以提供更多。假设当我说“服务器”时,我指的是实际“出售”具有NSConnection的对象的应用程序。“客户机”是同一应用程序的另一个实例,它向该应用程序获取代理

除了两个问题外,一切正常

  • 当充当服务器的应用程序试图拆除它正在出售的对象时,通过代理连接的任何客户端仍然保留。也就是说,即使在我调用下面的
    stopLocalServer
    函数之后,以前连接并获得代理对象的任何客户端应用程序仍然能够发送消息并调用服务器应用程序上的代码。在服务器调用
    NSConnection:invalidate
    后传递消息时,我希望客户端会抛出异常。如何在不要求服务器进程退出的情况下强制断开任何客户端

  • 在下面的
    startClientConnection
    代码中,如果服务器从未使用预期的注册名称出售对象,那么对客户端的
    NSConnection:connectionWithRegisteredName:host的调用将立即返回nil。这很好。但是,如果服务器已开始通过下面的
    startLocalServer
    代码出售对象,然后稍后停止使用
    stopLocalServer
    出售对象,则后续客户端连接尝试将挂起(永久阻止),直到服务器应用程序进程退出。对NSConnection:connectionWithRegisteredName的调用返回一个非nil对象,但对
    [\u 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;
    }
    

    回答我自己的问题。我仍然会坚持寻找更好的答案,或者如果有人能更好地解释为什么需要这样做的原因

    我相信
    stopLocalServer
    函数需要调用
    [[[u serverConnection receivePort]invalidate]
    ,以便关闭使用连接创建的端口。只需将该行添加到原始的
    stopLocalServer
    函数就可以解决我的问题。这会阻止进一步的连接尝试和消息成功

    更恰当的是,应用程序调用可以只拥有NSConnection使用的端口。因此,这成为启动和停止分布式对象侦听器的更好解决方案:

    -(void)startLocalServer:(NSString*)str
    {
        [self stopLocalServer];  // clean up any previous instance that might be running
        _port = [NSPort port];   // _port is of type NSPort*
        _serverConnection = [NSConnection connectionWithReceivePort:_port sendPort:nil];
        [_serverConnection setRootObject:self];
        [_serverConnection registerName:str];
    }
    
    
    -(void)stopLocalServer
    {
        [_serverConnection registerName:nil];
        [_serverConnection setRootObject:nil];
        [_serverConnection invalidate];
        _serverConnection = nil;
    
        [_port invalidate];
        _port = nil;
    }
    

    这似乎解决了上面的#1和#2问题。

    为了使客户端不会像您所描述的那样挂起,通常会设置一个超时,这可能与观察者相关,例如
    NSConnectionDidDieNotification
    。好主意。在生产代码中,超时和try/catch块都是使用NSConnection代码所必须的。超时无法解决问题。但我想我找到了一个满足#1和#2的答案。就我个人而言,我会先让连接失效,然后让端口失效。从连接下面使端口失效似乎是个坏主意。另外,请注意,
    -registerName:
    的文档指出,只有基于
    NSSocketPort
    的连接支持注销。另一种方法可能是使用
    NSConnectionDelegate
    方法加上观察
    NSConnectionDidDieNotification
    来跟踪从连接生成的子连接,并在停止服务器时使这些子连接失效。