【詳解objc_msgSend】
1、為了性能,objc_msgSend用匯編寫成。存在於objc-msg-x86_64.s中。
2、在上圖代碼中可以看到,objc_msgSend被分為2個過程:1)在cache中尋找SEL。2)在MethodTable尋找SEL。
3、CacheLookup中,不斷地拿SEL與cache中的緩存比較,比較失敗,則跳轉到 LCacheMiss標簽繼續在MethodTable中搜索。
如果想手動查找cache,則需要調用_cache_getimp函數(匯編實現),此函數是個對外接口層,用於保存與准備環境。
_cache_getImp在頭文件中objc-private.h中,鏈接后objc/c代碼可以直接調用。
4、MethodTableLookup 是個接口層宏,主要用於保存環境與准備參數,來調用 __class_lookupMethodAndLoadCache3函數(此函數實現於objc-class.mm)。
5、__class_lookupMethodAndLoadCache3函數也是個接口層(C編寫),此函數提供相應參數配置,實際功能在lookUpMethod函數中。
6、lookUpMethod函數實現遍歷method_list_t,從子類開始,一直遍歷到根類。此函數代碼較大,不貼圖了。文件在objc-class中。
【Cache Of lookUpMethod】
To speed the messaging process, the runtime system caches the selectors and addresses of methods as they are used. There’s a separate cache for each class, and it can contain selectors for inherited methods as well as for methods defined in the class. Before searching the dispatch tables, the messaging routine first checks the cache of the receiving object’s class (on the theory that a method that was used once may likely be used again). If the method selector is in the cache, messaging is only slightly slower than a function call. Once a program has been running long enough to “warm up” its caches, almost all the messages it sends find a cached method. Caches grow dynamically to accommodate new messages as the program runs.