0

私はiOSでスレッドを行うのが全く新しいです。次のように私は、タブとタブバーベースのアプリケーションを持っている:だけinitメソッドで多額のWebサービス呼び出しを持っているselectedSegmentIndex applicationDidFinishLaunchWithOptions内のdispatch_async呼び出しが期待通りの動作をしません。

  • 情報一覧画面を変更する機能ボタンが付い

    • ホーム画面を[self doLoadData]
    • つこの目的のため、私は先に行くと、私は実際にtabBarController.selectedSegmentIndex = 1を呼び出す前に、そのinitメソッドを呼び出したい

    のために重要ではありません他の画面。だから、私は私のapplicationDidFinishLaunchingでこれをやった:

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [Constants configureApp];

    self.window.rootViewController = self.navigationController; 
    
    dispatch_async(dispatch_get_global_queue(0, 0), ^{ 
        [[[[tabBarController viewControllers] objectAtIndex:1] topViewController] init ]; 
        [self.window addSubview:tabBarController.view]; 
        [self.window makeKeyAndVisible]; 
    }); 
    

    これの動作は、それは一種のそれことで動作しないことです:

    1. 表示スプラッシュDefault.png
    2. は白を表示しますscreen
    3. 最後に、tabBarControllerでMainWindowを表示します。

    私はそれがすべて間違っていることを知っているので助けてください!

  • 答えて

    1

    さまざまなタスクをキューに任意にディスパッチすることはできませんし、それがうまくいくことを期待してください。

    クラスおよび/またはメソッドがスレッドセーフであると明示的に記述されていない限り、はスレッドセーフではありませんです。

    また、スレッドセーフであるように独自のクラスを非常に慎重に設計する必要があります。キューではこれを簡単に行うことができますが、それはまだ鋭いエッジで蔓延しています。

    この場合、メインキューからUIKitオブジェクトを削除しています。これは一般的にいくつかの特定の文脈の外では動詞である。

    詳細については、Concurrency Programming Guideをお読みください。

    2

    bbumと同じように、UIKitはスレッドセーフではありません。 initをバックグラウンドで投げるのではなく、initを遅くしてそこから作業する部分を自分自身に尋ねてください。

    ウェブから画像を読み込んだり、ファイルを解析していますか?これらはグランドセントラルディスパッチを使ってバックグラウンドに入れられるものの良い例です(少なくとも画像のダウンロード部分で、表示はメインスレッドで行われるべきです)。代わりに派遣全体のinitを包むの、ビューコントローラのinitメソッドでは、このような何かをしようと

    :これを行うとき

    dispatch_async(queue, ^{ 
        [self doLoadData] 
        dispatch_async(dispatch_get_main_queue(), ^{ 
        //Set new data to be displayed  
        }); 
    }); 
    

    は、(ビューはデータなしで大丈夫に見えることを、確認してくださいデータがダウンロードされる前に表示されるため、一度ダウンロードしたデータは正常にダウンロードされます)。

    関連する問題