3

我正在编写一个必须与通过 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....];
    }
  } 
}

发送数据后,应用程序等待接收数据或rxTimeoutTimer触发数据包,从而重新传输数据包。rx 操作有效,因为底层使用异步系统调用并调用看起来基本上像这样的 rx 处理程序。

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

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

谢谢。

4

4 回答 4

9
CFRunLoopStop([runLoop getCFRunLoop]);
于 2010-01-11T21:04:12.777 回答
4

标准模式是运行 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;
}
于 2010-01-11T21:05:03.897 回答
0

CFRunLoopStop([runLoop getCFRunLoop]); 和 CancelPerformSelector

对我不起作用,请参阅我的运行代码 [NSRunLoop 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 无效];

于 2014-09-22T06:41:25.830 回答
0

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

 -(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;
    }

kennytm 的答案似乎是正确的。

于 2015-12-14T11:02:37.097 回答