このことを考慮:
@interface SomeViewController : UIViewController {
SomeChildObject *child;
}
@end
@implementation SomeViewController
- (void) viewDidLoad {
...
child.delegate = self;
}
- (void) somethingHappened {
NSInvocationOperation *operation = [[NSInvocationOperation alloc]
initWithTarget:child
selector:@selector(doSomething)
object:nil];
[someNsOperationQueue addOperation:operation];
[operation release];
}
- (void) callbackA:(SomeData *)someData {
[self performSelectorOnMainThread:@selector(callbackAonMainThread:)
withObject:someData
waitUntilDone:NO];
}
- (void) callbackAonMainThread:(SomeData *)someData {
... do something with results in main thread, e.g UI feedback
}
- (void) callbackB:(SomeData *)someData {
[self performSelectorOnMainThread:@selector(callbackBonMainThread:)
withObject:someData
waitUntilDone:NO];
}
- (void) callbackBonMainThread:(SomeData *)someData {
... do something with results in main thread, e.g UI feedback
}
@end
英語で:
メインスレッドでビューコントローラーを実行し、子モデルオブジェクトを使用して何かを実行します(ネットワーク経由でデータをフェッチします)。ビュー コントローラーは子のデリゲートであるため、子はデリゲートによって結果を通知できます。コストのかかる作業を実行するために、バックグラウンド スレッドで操作を起動する NSInvocationOperation を使用して child.doSomething メソッドを生成します。完了すると、子はデリゲート (ビュー コントローラー) の callbackA または callbackB を呼び出して結果を返します。これらのコールバックは、doSomething 呼び出しが実行されたのと同じバックグラウンド スレッドで呼び出されるため (私が思うに)、私は performSelectorOnMainThread を呼び出して制御をメイン スレッドに戻す必要があります。
これは問題なく動作しますが、コールバックごとに 2 つのコールバック関連のメソッドを用意するのは好きではありません。(実際にはより多くのコールバックがあるため、実際のコードはさらに肥大化しています。) 理想的には、次のようにします。
- (void) callbackA:(SomeData *)someData {
if (not_running_on_main_thread) {
[self performSelectorOnMainThread:@selector(callbackA:)
withObject:someData
waitUntilDone:NO];
} else {
// now running on main thread, work with the results.
}
}
質問:
1) 「not_running_on_main_thread」テストを行うにはどうすればよいですか?
2) コールバックの肥大化を抑える他の方法はありますか?
編集:わかりました、投稿する前にNSThreadドキュメントを読んだことはありません:) [NSThread isMainThread]が探しているもののようです。しかし、これを再構築またはより良くする他の方法はありますか?