スレッド内のビューの変更で問題が発生していました。サブビューを追加しようとしましたが、表示に約6秒以上かかりました。ようやく機能しましたが、正確にはわかりません。だから私はそれがなぜ機能し、次の方法の違いは何なのかと思っていました:
//this worked -added the view instantly
dispatch_async(dispatch_get_main_queue(), ^{
//some UI methods ej
[view addSubview: otherView];
}
//this took around 6 or more seconds to display
[viewController performSelectorOnMainThread:@selector(methodThatAddsSubview:) withObject:otherView
waitUntilDone:NO];
//Also didnt work: NSNotification methods - took also around 6 seconds to display
//the observer was in the viewController I wanted to modify
//paired to a method to add a subview.
[[NSNotificationCenter defaultCenter] postNotificationName:
@"notification-identifier" object:object];
参考のために、これはACAccountStoreのクラスのこのCompletetion Handler内で呼び出されました。
accountStore requestAccessToAccountsWithType:accountType withCompletionHandler:^(BOOL granted, NSError *error) {
if(granted) {
//my methods were here
}
}
編集:うまくいかなかったと言ったとき、追加したビューを表示するには約6秒かかりました。
デフォルトでは、_-performSelectorOnMainThread:withObject:waitUntilDone:
_はデフォルトの実行ループモードで実行するセレクターのみをスケジュールします。実行ループが別のモード(トラッキングモードなど)にある場合、実行ループがデフォルトモードに戻るまで実行されません。バリアント_-performSelectorOnMainThread:withObject:waitUntilDone:modes:
_でこれを回避できます(実行するすべてのモードを渡すことにより)。
一方、dispatch_async(dispatch_get_main_queue(), ^{ ... })
は、メイン実行ループが制御フローをイベントループに戻すとすぐにブロックを実行します。モードは気にしません。そのため、モードについても気にしたくない場合は、dispatch_async()
がより良い方法かもしれません。
performSelectorOnMainThread:withObject:waitUntilDone:
は、一般的な実行ループモードでメッセージをキューに入れます。 AppleのConcurrency Programming Guide によると、メインキューは、キューに入れられたタスクをアプリの実行ループからの他のイベントとインターリーブします。したがって、イベントキューに処理する他のイベントがある場合、後で送信されたとしても、ディスパッチキューのキューに入れられたブロックが最初に実行される可能性があります。
この記事 はperformSelectorOnMainThread
対dispatch_async
、上記の質問にも答えます。
waitUntilDone=YES
でthe PerformSelectorOnMainThread
を試しましたか
例えば:
コード:
[viewController performSelectorOnMainThread:@selector(methodThatAddsSubview:) withObject:otherView waitUntilDone:YES];
PerformSelectorOnMainThread
が応答するのに非常に時間がかかる理由については、これで問題を解決できると思います。