【问题标题】:How to synchronously wait for reply block when using NSXPCConnection使用 NSXPCConnection 时如何同步等待回复块
【发布时间】:2016-02-10 00:49:35
【问题描述】:

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

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

我这样称呼:

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

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

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


进一步澄清上面的 sn-p:proxy 对象是使用remoteObjectProxy 方法从NSXPCConnection 对象获得的远程对象。这是一个重要的细节,因为这会影响调用回复块的队列。

【问题讨论】:

    标签: objective-c multithreading cocoa xpc nsxpcconnection


    【解决方案1】:

    我刚刚发现了一种可能更好的方法:

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

    不需要信号量或组。

    【讨论】:

      【解决方案2】:

      这就是调度组的目的。

      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)。

      【讨论】:

        【解决方案3】:

        我建议使用 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;
        

        【讨论】:

        • 这就是我最终所做的(或多或少)
        【解决方案4】:

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

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

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


        像这样:

        __block NSInteger status;
        [proxy addItem:data withLabel:@"label" reply:^(NSInteger rc) {
                     status = rc;
                     // like this ...
                     [someObject processReturnedStatus];
                 }
        ];
        

        【讨论】:

        • 调用这段代码的方法应该是返回状态码,我真的别无选择:这是一个不受我控制的接口。
        猜你喜欢
        • 2020-03-29
        • 1970-01-01
        • 2018-06-17
        • 1970-01-01
        • 1970-01-01
        • 2020-05-12
        • 1970-01-01
        • 1970-01-01
        • 2021-05-25
        相关资源
        最近更新 更多