2

我正在使用 NSXPCConnection 并且我的一个接口调用有一个回复块,如下所示:

- (void)addItem:(NSData *) withLabel:(NSString *) reply:(void (^)(NSInteger rc))reply;

我这样称呼:

__block NSInteger status;
[proxy addItem:data withLabel:@"label" reply:^(NSInteger rc)
         {
             status = rc;
         }
];

我的理解是回复块异步运行,并且可能在方法返回之后运行。

我想同步测试返回码,最好的方法是什么?


为了进一步阐明上面的代码片段:对象是使用该方法proxy从对象获得的远程对象。这是一个重要的细节,因为这会影响调用回复块的队列。NSXPCConnectionremoteObjectProxy

4

4 回答 4

12

我刚刚发现了一个可能更好的方法来做到这一点:

在创建远程对象时使用synchronousRemoteObjectProxyWithErrorHandler而不是。remoteObjectProxy

不需要信号量或组。

于 2018-08-24T23:41:59.757 回答
4

这就是调度组的目的。

NSTimeInterval timeout = 120; // in seconds
__block NSInteger status;

dispatch_group_t syncGroup = dispatch_group_create();
dispatch_group_enter(syncGroup);

[proxy addItem:data withLabel:@"label" reply:^(NSInteger rc)
    {
        status = rc;
        dispatch_group_leave(syncGroup);
    }
];

dispatch_time_t waitTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(NSEC_PER_SEC * timeout));

if(dispatch_group_wait(syncGroup, waitTime) != 0)
{
    // complain about a request timing out
}

// enjoy your status

如果你选择使用 remoteObjectProxyWithErrorHandler 来获取你的代理,那么你需要记住在你的错误处理程序中调用 dispatch_group_leave(syncGroup)。

于 2016-03-05T00:21:48.187 回答
2

我想同步测试返回码,最好的方法是什么?

你真的不希望它同步运行。那只会阻塞正在运行该块的队列/线程,并且通常会导致严重的崩溃。

相反,在该status = rc;行之后,调用可以处理它已完成的事实的东西。让方法返回,让队列或事件循环运行,然后在完成时执行所需addItem:withLabel:的工作。


像这样:

__block NSInteger status;
[proxy addItem:data withLabel:@"label" reply:^(NSInteger rc) {
             status = rc;
             // like this ...
             [someObject processReturnedStatus];
         }
];
于 2016-02-10T05:06:29.610 回答
2

我建议使用 dispatch_semaphore。

// Create it before the block:
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
__block NSInteger status = 0;
[proxy addItem:data withLabel:@"label" reply:^(NSInteger rc) {
             status = rc;
             // In the block you signal the semaphore:
             dispatch_semaphore_signal(semaphore);
         }
];

// here wait for signal
// I dont remember exactly function prototype, but you should specify here semaphore and the time waiting (INFINITE)
dispatch_semaphore_wait(...);

// in non-ARC environment dont forget to release semaphore
dispatch_release(semaphore);

return status;
于 2016-03-06T13:52:40.047 回答