2013-02-24 87 views
12

我是新來的客觀C,來自.NET和Java背景。在後臺線程上創建視圖,在主線程中添加主視圖

所以我需要以異步方式創建一些UIWebViews中,我使用

 dispatch_queue_t queue = dispatch_queue_create("myqueue", NULL); 
    dispatch_async(queue, ^{ 
     // create UIwebview, other things too 
      [self.view addSubview:webView]; 
     }); 

你owuld想象這是我自己的隊列這樣做會引發錯誤:

bool _WebTryThreadLock(bool), 0xa1b8d70: Tried to obtain the web lock from a thread other 
    than the main thread or the web thread. This may be a result of calling to UIKit from a 
    secondary thread. Crashing now... 

所以,我該怎麼加主線程的子視圖?

回答

16

。我不會使用performSelectorOnMainThread:withObject:waitUntilDone:,而是在主隊列上執行子視圖添加。

dispatch_queue_t queue = dispatch_queue_create("myqueue", NULL); 
dispatch_async(queue, ^{ 
    // create UIwebview, other things too 

    // Perform on main thread/queue 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     [self.view addSubview:webView]; 
    }); 
}); 

它是細實例化UIWebView上的背景隊列。但要將它作爲子視圖添加,您必須位於主線程/隊列中。從UIView文檔:

線程注意事項

操作,以應用程序的用戶界面必須在主線程上發生。因此,您應該始終從應用程序主線程中運行的代碼中調用UIView類的方法。唯一不是嚴格需要的時候是創建視圖對象本身,但所有其他操作應該在主線程上進行。

+0

要小心,即使initWithFrame不保證是線程安全的。請參閱http://stackoverflow.com/questions/11122957/is-it-ok-to-create-a-uiview-on-a-background-thread – stefreak 2015-02-12 17:53:33

+0

也許我對'線程安全'的理解是錯誤的。但我認爲線程安全意味着可以同時從多個線程操縱一個對象。例如。你可以考慮一個線程安全的數組,它可以讓你從多個線程中添加對象。 然而,在這種情況下,我們沒有操縱或訪問來自多個線程視圖對象/同時隊列。我們在一個線程/隊列上創建它,然後將其交給另一個線程/隊列。 – Florian 2015-02-12 19:00:20

+0

事實證明,我所鏈接的問題的答案是誤導 - 抱歉。蘋果表示:「唯一一次可能不是絕對必要的是創建視圖對象本身,因此它應該是安全的。 – stefreak 2015-02-12 20:41:12

2

大多數UIKit對象,包括UIView的實例,必須從主線程/隊列操作只有。您無法將消息發送到任何其他線程或隊列上的UIView。這也意味着你不能在任何其他線程或隊列上創建它們。

+5

這不完全正確。在後臺實例化視圖是完全正確的。從UIView文檔:操作到應用程序的用戶界面必須在主線程上進行。因此,您應該始終從應用程序主線程中運行的代碼中調用UIView類的方法。唯一不是嚴格需要的時候是創建視圖對象本身,但所有其他操作應該在主線程上進行。 – Florian 2013-02-24 07:48:08

+0

@Florian如果兩個視圖都不與UI交互,在後臺使用方法addSubview是否正確? – 2017-06-12 12:22:11

+0

@BohdanSavych我不確定。你的用例是什麼? – Florian 2017-06-16 06:40:33

1

正如羅布說的用戶界面的變化應該只在主thread.You完成試圖既然你已經使用了調度隊列從二級thread.Change添加代碼[self.view addSubview:webView];

[self.view performSelectorOnMainThread:@selector(addSubview:) withObject:webView waitUntilDone:YES];

相關問題