我正在比較不同的編程語言和開發平臺。 objective-c和其他語言之間的一個重要區別是,它使用選擇器和消息,所以每次調用objc_msgSend時,都要跨越共享庫的邊界,因此引入了可測量的開銷,並且爲objc_msgSend增加了額外的開銷(在緩存的情況下很少)內部功能,像這裏解釋: http://www.mulle-kybernetik.com/artikel/Optimization/opti-3.html 我不是專家,所以我不得不相信這篇文章,在這個論壇上找到。 在官方Apple指南中,我發現「點語法」只是「語法糖」,即使用了相同的方法調用機制。 問題:我想知道,純粹的調用是在類實例內部執行的,在這種情況下調用objc_msgSend是一種浪費。那就是當一個類實例的方法從同一個類實例的方法中被調用時。 謝謝objective-c:方法仍在調用選擇器或純調用的類中調用?
回答
所有Objective-C方法調用使用obj_msgSend。這是因爲代碼不知道self
的實際類。即:它可能是另一個實現的子類,或者甚至是由遠程機器通過xmlrpc實現的方法的代理。如果你知道你要經常發送消息X到對象Y,你可以通過抓取給定對象的選擇器的實現來自己優化。
考慮這種情況在一個假設的OOP語言:
class A {
say_something(){
print("A!")
}
do_something(){
say_something()
}
}
和
class B : extends A {
say_something(){
print("B!")
}
}
現在,假設你有B
一個實例,並調用do_something
:
B b;
b.do_something();
應該b
打印A
或B
?如果在執行do_something
時調用vtable
(使用C++)或obj_msgSend
(使用Obj-C),它將打印B
,但如果編譯器決定調用同一類中的方法,則應調用方法在同一個類中,它將打印A
。
哪一個取決於具體情況。因此,在C++中,您可以通過標記成員函數virtual
來進行選擇。在Objective-C中,每種方法都是虛擬的。
因此,即使在C++中,您所建議的優化也不會對虛擬方法進行。如果沒有虛擬方法,我不會說一種適當的OOP語言。
無論如何,現在您可能擔心它會降低Obj-C應用程序的性能。蘋果知道危險,所以他們有很多很多的優化。例如,在最近的運行時中,objc_msgSend
位於固定地址,因此您不必首先瀏覽共享庫邊界。
Mulle-Kybernetic的文章也很好,但也注意到它很過時:十年前它就是高潮,這在這個行業是一個史前時代。您可以閱讀關於objc_msgSend
在bbum's blog posts或Hamster's blog posts中實施的最新優化。
如果您正在編寫管理UI的代碼,請使用標準消息傳遞(即,幕後的objc_msgSend
)完全夠用了。它甚至能在移動設備上非常流暢地運行!因此,不要通過獲得IMP
等來進行不成熟的優化,直到在測量代碼的性能之後它變得絕對必要爲止。
如果你正在編寫一個涉及數萬個粒子移動的計算密集型代碼,是的,我建議不要使用Obj-C消息框架。在這種情況下,只需簡單地編寫一個C代碼(可以在Objective-C中使用)或C++代碼(可在Objective-C++中使用)。
它仍然通過objc_msgSend和變體使用動態分派。
理想情況下,將爲objc類型生成與JIT類似的內容。
不像objc,C++編譯器可以使用靜態調度呼叫到C++被標記虛擬當它可以確定類型類型。
無論如何,有很多方法可以優化 - 你可以先用C++實現,然後使用objc,它真的很方便......但我不確定你到底想要完成什麼。
- 1. 調用C++方法回調ObjectiveC
- 2. 從ObjectiveC中調用子方法(IOS6)
- 3. 是否在ObjectiveC中調用超類問題的方法?
- 4. 調用委託方法和調用選擇器
- 5. 未調用選擇器方法
- 6. 在線程中調用純虛方法
- 7. 從Objectivec中調用C main
- 8. 或調用方法?
- 9. 如何在LINQ選擇調用方法
- 10. 調用方法NodeJS/ES6中的類調用自己的方法
- 11. 在具體類的線程中調用的純虛方法
- 12. Cocos2d:CCMenuItem的選定方法中的調用選擇器
- 13. 延遲的類選擇器調用
- 14. 調用類方法
- 15. 在ES6類的數組中使用回調的調用方法
- 16. 從類中調用方法
- 17. 如何調用類的回調方法?
- 18. 調用超類方法後調用子類方法
- 19. UIPanGesture選擇器方法沒有在iPhone SDK(iOS 5.1)中調用
- 20. 選擇UITabBar時調用方法?
- 21. Mockito.verify選擇性方法調用
- 22. 選擇日期後調用方法
- 23. 從objectiveC調用javascript函數
- 24. SWTableviewcell - 調用動畫方法,不用刷卡或選擇
- 25. 實例化T調用方法中的類可調用類
- 26. NSTimer選擇器調用
- 27. orderBySortDescriptor不調用選擇器
- 28. 調用helper方法調用
- 29. 選擇器在cocos2d調度方法
- 30. 在JavaScript中調用多個選擇器
你指的是IMP嗎?對於課堂內的每一個電話來說,這是多麼糟糕的事情。然而,編譯器是否能夠理解實例在編譯時調用自己?很奇怪。我的意思是,我沒有使用選擇器語法來調用同一個實例的方法,是嗎? – P5music
@ P5music:即使在C++中,從類的成員函數的實現中調用類的虛方法,也會通過虛函數表。在Objective-C中,每個方法調用都是虛擬的。所以它通過'objc_msgSend'設施進行調用。別擔心,蘋果知道'objc_msgSend'是絕對關鍵的,所以他們付出了很大的努力來調整它,使用手寫彙編和大量的黑客手段。 – Yuji