非常によく似た問題はすでにhereで議論されています。手元の問題と私が達成しようとしているのは、作成されたスレッド内の特定のオブジェクトに対して関数を呼び出すことです。Objective-C:スレッドが主なものでない場合、[NSObject performSelector:onThread ...]は呼び出されません
- クラスAのインスタンスが所与
NSThread
(スレッドA)で作成された(しない主なもの):ここで、完全なケースです。このインスタンスは、メンバー変数として、NSThread
の作成を保持します。 クラスBのインスタンスは、別の
NSThread
- スレッドBで実行されているメンバ関数の1つを持ち、Aの作成スレッドのAの関数を呼び出したいとします。したがって、Bの現在実行中の関数は、次の呼び出しを発行します。[_a performSelector: @(fun) onThread: _a.creationThread withObject: nil waitUntilDone: NO];
Aのインスタンスの作成スレッドは、メイン1、fun
が呼ばれることは決してありませんされていない場合。作成スレッドが主スレッドの場合、常に呼び出されます。最初に、Aのインスタンスを作成したスレッドが破棄され、ポインタが無効なスレッドを指しているのに、スレッドオブジェクト(スレッドA)の関数を実際に呼び出すと、有効な結果が得られ、クラッシュは発生しないと考えていました。また、オブジェクトのチェックはthis checkに従って有効です。助言がありますか?
更新:
私はバックグラウンドスレッドでタイマーを作成してやってる:
_timer = [NSTimer timerWithTimeInterval:60.0 target:self selector:@selector(fun:) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSDefaultRunLoopMode];
このコードは、タイマーを開始するものです。タイマーは、特定のバックグラウンドスレッドでは開始されません。タイマーを作成する関数はどのスレッドでも呼び出すことができます。したがって、タイマーは、NSTimerのドキュメントの状態とまったく同じもので無効にする必要があります。「タイマーがインストールされている同じスレッドからinvalidateメソッドを呼び出す必要があります。
。 (b)実行ループが走っている場合。 (c)そのスレッドをブロックしているものがあれば。私はあなたの質問を編集し、スレッドの作成と起動と実行ループの開始を示す問題の[非常に小さな再現可能な例](http://stackoverflow.com/help/mcve)を含めることをお勧めします。既存のコードをすべて表示するのではなく、動作を再現するために最小限に留めることをお勧めします。 – Rob
(さておき、GCDはこのようなものがはるかに容易になりますが、私はあなたが 'NSThread'を使用するためにいくつかの説得力のある理由があるとします。として)私は小さな再現性の例を作成しようとしていましたが、代わりに問題を修正するに焦点を当てました。 GCDは役に立ちません - オブジェクトAの特定のスレッドで作成されたタイマーがあり、同じスレッドで無効にする必要があります。タイマー作成の瞬間にコールをディスパッチするキューをキャッシュできません - 'dispatch_get_current_queue()'は推奨されていません。また、 'NSThread'、ディスパッチキュー、NSOperationsを混在させることはあまり健康的ではないことを知っています。私はスレッドやディスパッチキューのいずれかをキャッシュする方法が嫌いですが、それ以上の提案があれば共有してください。 – Ivan
GCDディスパッチタイマーソースを使用できます。それらは任意のスレッドから取り消すことができます。 –