下面是使用block
調用代碼:這兩個方法在obj-c中調用主線程有什麼不同嗎?
dispatch_async(dispatch_get_main_queue(), ^{
[self doSomething];
});
而這一次使用selector
呼籲:
[self performSelectorOnMainThread:@selector(doSomething)
withObject:nil
waitUtilDone:NO];
下面是使用block
調用代碼:這兩個方法在obj-c中調用主線程有什麼不同嗎?
dispatch_async(dispatch_get_main_queue(), ^{
[self doSomething];
});
而這一次使用selector
呼籲:
[self performSelectorOnMainThread:@selector(doSomething)
withObject:nil
waitUtilDone:NO];
是 - 在第一種情況下,你創建塊和張貼關閉的主隊列。 dispatch_async
將copy
該塊。複製塊會導致它保留其引用的每個對象。所以self
將被保留,就像你在塊中提到的任何其他對象一樣。 Grand Central Dispatch是Grand Block Dispatch的重要組成部分。
在第二種情況下,您只需在主線程上安排致電doSomething
。進行調用的機制將是一個運行循環。 self
並且至多隻有一個參數對象將被保留。
GCD和運行循環的區別在於運行循環有模式。只有在運行循環處於兼容模式時,才能對隊列進行排隊。在實踐中,你最常用的方法是排隊等待NSDefaultRunLoopMode
。當用戶與用戶界面交互時,它將切換到默認模式以外的模式。因此,在用戶停止交互之前,您的工作不會發生。例如。在iOS上,用戶被認爲是在他們的手指停止時進行交互。因此,您可以安排您認爲重要的工作,例如平滑滾動以繼續進行,直到用戶完成交互後纔會發生。
您提名的選擇器將使用NSRunLoopCommonModes
,其中包括跟蹤(用戶交互)模式,但與performSelectorOnMainThread:...modes:
進行比較和對比。
你確定嗎?我很確定'performSelectorInMainThread:...'確實保留了接收者以及參數。 – Chuck
@Chuck我在文檔中找不到明確的答案,但簡單的測試表明你是對的,所以這是一個非常安全的猜測,通過調用'NSRunLoop' - performSelector:target:argument:order:modes:' – Tommy