簡體   English   中英

applicationDidFinishLaunchWithOptions中的dispatch_async調用不符合我的期望

[英]dispatch_async call in applicationDidFinishLaunchWithOptions not behaving the way I would expect

我對iOS中的線程是全新的。 我有一個帶有標簽的基於標簽欄的應用程序,如下所示:

  • 主屏幕帶有僅用於更改selectedSegmentIndex按鈕
  • 在init方法[self doLoadData]中具有大量Web服務調用的信息列表屏幕
  • 其他兩個與此無關的屏幕

我想繼續調用該init方法,然后再實際調用tabBarController.selectedSegmentIndex = 1 所以,我在我的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. 顯示Splash Default.png
  2. 顯示白屏
  3. 最后顯示帶有tabBarController的MainWindow。

請幫忙,因為我知道我做錯了!

就像bbum所說的那樣,UIKit不是線程安全的。 不要問自己將init放在后台的原因,而要問自己是什么原因使init變慢並從那里開始工作。

您是從Web加載圖像還是正在解析某些文件? 這些都是使用Grand Central Dispatch放回后台的好例子(至少是圖像的下載部分,顯示仍應在主線程中完成)。

而不是將整個init打包在分派中,請在視圖控制器的init方法中嘗試以下操作:

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

執行此操作時,請確保該視圖在沒有數據的情況下看起來還不錯(並在正常下載后加載數據),因為它將在完成下載之前顯示。

您不能隨意將各種任務分派到隊列中,也不能希望它能工作。

除非明確將類和/或方法記錄為線程安全的,否則它不是線程安全的

同樣,您必須非常仔細地設計自己的類以確保線程安全。 盡管隊列使此操作更容易進行,但仍然充滿鋒利的邊緣。

在這種情況下,您將使UIKit對象脫離主隊列。 通常,這是在某些特定上下文之外的。

您需要閱讀《 並發編程指南》以了解詳細信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM