3

USB 経由で接続されたデバイスと通信する必要があるアプリケーションを作成しています。アプリは決まったタイミングでデバイスから順番にデータを送受信します。そうしないと UI がブロックされるため、すべての Rx/Tx は別のスレッドで発生します。基本的な構造は基本的にこのようになります。(自動解放プールなどは省略)

-(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-handlerを呼び出すため、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

標準的なパターンは、一定のタイムアウト期間 (0.5 秒など) の間 runloop を実行し、タスクが完了するまで繰り返すことです。

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 に答える