[英]dispatch_async call in applicationDidFinishLaunchWithOptions not behaving the way I would expect
我對iOS中的線程是全新的。 我有一個帶有標簽的基於標簽欄的應用程序,如下所示:
selectedSegmentIndex
按鈕 [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]; });
這樣做的行為在於它可以完成以下工作:
請幫忙,因為我知道我做錯了!
就像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.