Cocoa 如何退出[nsrunlop runUntilDate]?

Cocoa 如何退出[nsrunlop runUntilDate]?,cocoa,macos,nsthread,nsrunloop,Cocoa,Macos,Nsthread,Nsrunloop,我正在编写一个应用程序,它必须与通过USB连接的设备进行通信。该应用程序在固定的时间从设备依次发送和接收数据。所有接收/发送都发生在一个单独的线程中,因为否则UI将被阻塞。基本结构基本上是这样的。(自动释放池和内容省略) 发送数据后,应用程序等待接收数据或触发导致数据包重新传输的rxtimeoutimer。rx操作之所以有效,是因为底层使用异步系统调用并调用rx处理程序,其基本外观如下 -(void)receiveData:(NSData*)data{ [rxQueue addObject:

我正在编写一个应用程序,它必须与通过USB连接的设备进行通信。该应用程序在固定的时间从设备依次发送和接收数据。所有接收/发送都发生在一个单独的线程中,因为否则UI将被阻塞。基本结构基本上是这样的。(自动释放池和内容省略)

发送数据后,应用程序等待接收数据或触发导致数据包重新传输的
rxtimeoutimer
。rx操作之所以有效,是因为底层使用异步系统调用并调用rx处理程序,其基本外观如下

-(void)receiveData:(NSData*)data{
  [rxQueue addObject:data];
  [rxTimeoutTimer invalidate];  // cancel timeout
}
是否有(简单的)方法使
[runLoop runUntilDate:
退出
接收数据:
?苹果的文档说,删除所有计时器源并不能保证RunLoop退出。我读了一些关于调用
性能选择器:onThread:…
的内容,但它要么不起作用,要么我没有抓住要点


谢谢。

标准模式是运行runloop一段超时时间(例如0.5秒),然后迭代直到任务完成:

CFRunLoopStop([runLoop getCFRunLoop]);
while(state == kIsConnected) {
  while(!iterationDone) {
    [runLoop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.5]];
    //do other stufff
  }
}

-(void)receiveData:(NSData*)data{
  [rxQueue addObject:data];
  [rxTimeoutTimer invalidate];  // cancel timeout
  iterationDone = YES;
}
CFRunLoopStop([runLoop getCFRunLoop]); 和 取消性能选择器

不为我工作, 请参阅我的运行代码[nsrunlop currentRunLoop]

timerUpdateLocation = [NSTimer scheduledTimerWithTimeInterval:[time intValue] target:self selector:@selector(startTrackingBg) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timerUpdateLocation forMode:NSRunLoopCommonModes];
[[NSRunLoop currentRunLoop] run];
为了停止它,我只是使计时器失效

[timerUpdateLocation invalidate]


这样做可以退出。但它会在几秒钟后退出

 -(void)comThread:(id)arg {
      BOOL ret = YES;
      rxTimeoutTimer = [NSTimer scheduledTimer....];
      while(ret) {
        // let timers run
        ret = [runLoop runUntilDate:[NSDate distantFuture]];
      } 
    }
    -(void)receiveData:(NSData*)data{
      [rxQueue addObject:data];
      [rxTimeoutTimer invalidate];  // cancel timeout
      iterationDone = YES;
    }

肯尼特的答案似乎是正确的。

就我而言,整个超时时间是0.5秒。我必须在这段时间内运行RunLoop,比如0.05秒。我想知道它是否真的有这样的分辨率。它真的有这样的分辨率。带有
distantFuture
参数的
-runMode:beforeDate:
方法也可能工作,因为它处理一个输入源,然后返回,此时将检查
while
条件,并且(如果是真的)重新启动运行循环。或者,不带“runLoop”局部变量:CFRunLoopStop([[NSRunLoop currentlunloop]getCFRunLoop])@rpj:在这种情况下使用
CFRunLoopGetCurrent()
 -(void)comThread:(id)arg {
      BOOL ret = YES;
      rxTimeoutTimer = [NSTimer scheduledTimer....];
      while(ret) {
        // let timers run
        ret = [runLoop runUntilDate:[NSDate distantFuture]];
      } 
    }
    -(void)receiveData:(NSData*)data{
      [rxQueue addObject:data];
      [rxTimeoutTimer invalidate];  // cancel timeout
      iterationDone = YES;
    }