私はタイマーとストリームを添付するNSRunLoopオブジェクトを持っています。それは素晴らしい作品です。それを止めることは別の話です。CFRunLoopRun()vs [NSRunLoop run]
[runLoop run]
を使用してループを実行します。
CRunLoopStop([[NSRunLoop currentRunLoop] getCFRunLoop])
を使用してループを停止しようとすると、ループは停止しません。代わりにCRunLoopRun()
を使用してループを開始すると、動作します。また、私のカスタム実行ループを実行しているスレッドで正しい呼び出しが行われていることを確認しました。私はpthread_self()
でこれをデバッグしました。
私はメーリングリストのアーカイブを見つけました。開発者は「実行メソッドNSRunLoop
を使用してループを開始した場合、CRunLoopStop()
を使用してください」と言っていました。なぜそれがそれであるのか理解できます。通常は、同じ関数セットからイニシャライザとファイナライザをペアにします。
NSRunLoop
を「CFに頼らずに」停止するにはどうすればよいですか? NSRunLoop
にはstop
メソッドが表示されません。すべての入力ソースを削除CFRunLoopStop()
- 設定、しかし:ドキュメントは、次の3つの方法で実行ループを停止することができますことを言いますあなたの背中の後ろに実行ループまあ
に何を立ち往生かを知ることはできませんので、これは私はすでに2を試してみましたが、あなたので、それを感じる「醜い」があります、実行ループを停止する信頼性の低い方法です。 CFを掘り起こす必要があります。 3.質問から外れています - 私は非決定論的なコードを好きではありません。
これは私に1を残します。ドキュメントを正しく理解していれば、既存の実行ループにタイムアウトを「追加」することはできません。新しい実行ループはタイムアウトでのみ実行できます。新しい実行ループを実行すると、ネストされた実行ループのみが作成されるため、問題は解決しません。私はまだ古いものに直ちにポップアップするでしょう、私は停止したいのと同じ...そうですか?私はこのことを誤解しているかもしれません。また、私はタイムアウト値でループを実行したくありません。私がするならば、CPUサイクルの焼き付け(低タイムアウト値)と応答性(高タイムアウト値)の間でトレードオフをしなければならないでしょう。
これは私が(擬似コードっぽい)今持っている設定です。
Communicator.h
@interface Communicator : NSObject {
NSThread* commThread;
}
-(void) start;
-(void) stop;
@end
Communicator.m
私は何@interface Communicator (private)
-(void) threadLoop:(id) argument;
-(void) stopThread;
@end
@implementation Communicator
-(void) start {
thread = [[NSThread alloc] initWithTarget:self
selector:@selector(threadLoop:)
object:nil];
[thread start];
}
-(void) stop {
[self performSelector:@selector(stopThread)
onThread:thread
withObject:self
waitUntilDone:NO];
// Code ommitted for waiting for the thread to exit...
[thread release];
thread = nil;
}
@end
@implementation Communicator (private)
-(void) stopThread {
CRunLoopStop([[NSRunLoop currentRunLoop] getCFRunLoop]);
}
-(void) threadLoop:(id) argument {
// Code ommitted for setting up auto release pool
NSRunLoop* runLoop = [NSRunLoop currentRunLoop];
// Code omitted for adding input sources to the run loop
CFRunLoopRun();
// [runLoop run]; <- not stoppable with
// Code omitted for draining auto release pools
// Code omitted for signalling that the thread has exited
}
@endif
何をする?それは一般的な/ CFで混乱する良いパターンですか?私は十分に財団を知らない。 CF層に干渉するのはおそらく危険です(メモリ破壊、不整合、メモリリークに関して)?私が達成しようとしているものを達成するための良いパターンがありますか?
ああ、賢い!私は 'runMode'が一度だけ走っているのを見ていませんでした。実行ループを何度も繰り返して起動すると、大きなパフォーマンス上のペナルティが発生しますか? –
いいえ、そこにはありません:それは ' - [NSRunLoop run]'と ' - [NSRunLoop runUntilDate:]'がどのように動作するかです。 –
runLoopIsStoppedをYESに設定するだけでスレッドは停止しません。 YESに設定し、そのrunloopのスレッドでアクションを実行する必要があります。そうしないと、[runLoop runMode:NSDefaultRunLoopMode beforeDate:date]は終了しません。 これは私が理解する年齢がかかりました。 – Pada