如何退出[NSRunLoop runUntilDate]?

ins*_*eat 3 macos cocoa nsthread nsrunloop

我正在编写一个必须与通过USB连接的设备进行通信的应用程序.应用程序在固定时间从设备轮流发送和接收数据.所有Rx/Tx都发生在一个单独的线程中,否则UI将被阻止.基本结构看起来基本上是这样的.(自动释放池和省略的东西)

-(void)comThread:(id)arg {
  while(state == kIsConnected) {
    // let timers run
    [runLoop runUntilDate:[NSDate distantFuture]];
    // handle data
    if(rxTxState == kRx) {
      // do some stuff to pass data to upper layers
      rxTxState = kTx;
    }
    if(rxTxState == kTx) {
      // do some stuff to send data
      rxTimeoutTimer = [NSTimer scheduledTimer....];
    }
  } 
}
Run Code Online (Sandbox Code Playgroud)

在发送数据之后,应用程序等待接收数据或者rxTimeoutTimer发送导致重新发送数据包的数据.rx操作有效,因为底层使用异步系统调用并调用一个看起来基本像这样的rx处理程序.

-(void)receiveData:(NSData*)data{
  [rxQueue addObject:data];
  [rxTimeoutTimer invalidate];  // cancel timeout
}
Run Code Online (Sandbox Code Playgroud)

有一种(简单的)[runLoop runUntilDate:]退出方式receiveData:吗?Apple文档说删除所有计时器源并不能保证RunLoop退出.我读了一些关于打电话的事情,performSelector:onThread:...但它要么不起作用,要么我没有明白这一点.

谢谢.

ken*_*ytm 9

CFRunLoopStop([runLoop getCFRunLoop]);
Run Code Online (Sandbox Code Playgroud)

  • @rpj:在这种情况下使用`CFRunLoopGetCurrent()`:) (3认同)

Bar*_*ark 5

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

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;
}
Run Code Online (Sandbox Code Playgroud)