0

特定の IP アドレスのポートに接続しようとしています。1 つの問題は、存在しない IP アドレスとの接続が確立されたときに書き込みコマンド (次のとおり) が実行されることです。

NSData * imageRequest = [@"640" dataUsingEncoding: NSUTF8StringEncoding];

int image = [self.outputImageStream write:[imageRequest bytes] maxLength:[imageRequest length]];

応答には 75 秒以上かかります。次のメソッド呼び出しでタイマーを開始することで、これに対処してみます。

self.connectionTimeoutTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(respondToTimer:)userInfo:nil repeats:NO];

私が定義した1秒間隔内では呼び出されません。

タイマーが 1 秒以内に作動するようにする方法はありますか?

4

1 に答える 1

2

これは、 NSTimer のリアルタイム動作に関する質問に答える可能性があります。

タイマーはリアルタイムのメカニズムではありません。タイマーが追加された実行ループ モードの 1 つが実行中で、タイマーの起動時間が経過したかどうかを確認できる場合にのみ起動します。典型的な実行ループが管理するさまざまな入力ソースのため、タイマーの時間間隔の有効な分解能は 50 ~ 100 ミリ秒程度に制限されます。長いコールアウト中、または実行ループがタイマーを監視していないモードのときにタイマーの起動時間が発生した場合、実行ループが次にタイマーをチェックするまで、タイマーは起動しません。したがって、タイマーが潜在的に起動する実際の時間は、スケジュールされた起動時間よりもかなりの時間になる可能性があります。

NSRunLoopCommonModesNSTimer のスケジュール方法は指定しませんが、次の代わりにスケジュールすると、パフォーマンスが向上する場合がありますNSRunLoopDefaultModes

[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];

これで改善されない場合は、低レベルの代替手段を探す必要があります。

特に、次のことを調べることができますCADisplayLink

CADisplayLink オブジェクトは、アプリケーションが描画をディスプレイのリフレッシュ レートに同期できるようにするタイマー オブジェクトです。

これは、NSTimer と非常によく似た方法で使用できます。

CADisplayLink の利点は、リフレッシュ レートにリンクされていることです。そのため、1/60 秒の時間間隔でかなり信頼性の高い動作が得られるはずです。

CADisplayLink の使用例:

CADisplayLink* displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(respondToTimer)];
[displayLink setFrameInterval:60];
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];

respondTimerこれにより、60 のリフレッシュ フレームごとに、つまり 1 秒に 1 回呼び出されます。メソッドを 1 つだけ呼び出す必要があるため、次を使用できます。

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC),
                           dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
                               [self respondToTimer];
                           });

そして、それはおそらくあなたにとってより簡単になるでしょう. (もちろん、[self RespondToTimer] への呼び出しをそのメソッドの完全な実装に置き換えることができます)。

于 2012-07-16T14:30:13.290 に答える