原文通過對Objective-C發展史、Objective-C中Runtime的動態派發,C語言的直接派發進行鋪墊介紹,引出了direct methods這個“新特性”(文章寫于2019年),
定義
看起來是個OC的方法,卻和C方法一樣,當被呼叫時,他是會直接使用而不是通過objc_msgSend,
使用方法
- 宣告/定義
針對@interface的成員變數或者方法的做法:
@interface MyClass: NSObject
@property(nonatomic) BOOL dynamicProperty;
@property(nonatomic, direct) BOOL directProperty;
- (void)dynamicMethod;
- (void)directMethod __attribute__((objc_direct));
@end
除了一個一個添加上去的做法,如果對@interface所有方法和成員屬性添加,用objc_direct_members屬性,使用之后,除了之前被此類宣告的所有方法和成員屬性之外,都會被認為是直接派發,
__attribute__((objc_direct_members))
@interface MyClass ()
@property (nonatomic) BOOL directExtensionProperty;
- (void)directExtensionMethod;
@end
對于@implementation,也是用objc_direct_members,不是先前宣告的成員也會被認為是直接派發(包括implicit methods),
__attribute__((objc_direct_members))
@implementation MyClass
- (BOOL)directProperty {…}
- (void)dynamicMethod {…}
- (void)directMethod {…}
- (void)directExtensionMethod {…}
- (void)directImplementationMethod {…}
@end
動態方法不能在子類重寫成直接方法
反之,直接方法也不能被重寫成動態方法
協議不可以宣告直接方法
反之,類不能以直接方法的形式實作協議方法
- 呼叫
之前已經提到,direct method看起來跟OC一樣,實際上使用的方法也跟OC一樣,
MyClass *object = [[[MyClass] alloc] init];
// Dynamic Dispatch
[object dynamicMethod];
// Direct Dispatch
[object directMethod];
性能評價
對于程式開發來講,“直接”自然比“間接”效率更高,那么direct method是否會真的對性能有很大增益呢?文章觀點卻是:
In most cases, making a method direct probably won’t have a noticeable performance advantage.
在絕大多數情況,“讓方法直接”可能不會有顯著的性能優勢,
因為事實證明,objc_msgSend已經是十分地快,這也得益其快取策略、底層優化、現代中央處理器固有的運行特性,個人認為前二者分別指的是:快速查找流程、其方法基于更靠近底層的匯編語言實作(詳細的可看開源代碼的objc-msg-arm64.s),第三者應該是硬體相關,有知道的同學歡迎補充,
原文在說明這點時還參考了自己的另一篇文章的鏈接,引文中,iPhone 6s在iOS 9.3.1上“Objective-C message send”運行1000000000(9個0)次共花了2.7s,如果是“IMP-cached message send”同樣次數自然是更短:1.2s,而“C++ virtual method call”運行了同樣次數也不過0.8s,這也擺明告訴我們:代碼慢僅僅是因為代碼爛而已(doge),
隱藏可見性
一個direct method,它的implementation會擁有隱藏可見性,也就是說,direct methods僅僅可以相同的module(文中還提到了個考究的說法,linkage unit)呼叫,他不會暴露在OC的runtime當中,
如果需要在代碼上測驗的同學可以用下面這段代碼:
MyClass *meClass = [[MyClass alloc]init];
BOOL respondToDynamicMethod = [meClass respondsToSelector:@selector(dynamicMethod)];
//以下兩行報錯:@selector expression formed with direct selector 'directMethod'
BOOL respondToDirectMethod = [meClass respondsToSelector:@selector(directMethod)];
[meClass performSelector:@selector(directMethod)];
隱藏可見性會帶來兩個直接的好處:
- 更小的二進制大小
- 沒有外部呼叫
部分英語單詞的含義
dispatch 分派/分發
Object-Oriented Programming(OOP) 面向物件編程
invoke 呼叫
maintain 維持
consult 查閱
inheritance chain 繼承鏈
deem 認為,視為
shebang 事情,作業
underlying implementation 底層實作
annotate 注釋,作注解
property declarations 屬性宣告
implicit methods 隱式方法
property synthesis
本文來自博客園,作者:MrYu4,轉載請注明原文鏈接:https://www.cnblogs.com/MrYU4/p/objectivec-direct-methods-xue-xi-bi-ji.html
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/442848.html
標籤:iOS
