1.存放自定義數據
數據管理三把劍:
get、set、remove ,用key 來作為存取數據的憑證
2.類的方法動態實現機制
方法存儲:
選擇子,oc對象的方法可視為簡單c函數,原型:
<return type>Class_selector(id self, SEL _cmd,...)
方法維護:
快速緩存表:存儲選擇子和方法的對應關系
方法調用:
objc_msgsend(some object,@selector(),parameters)去查找快速緩存表,涉及到消息轉發
3.消息轉發機制:(message forwarding)

三步分別是:說,這個是不是你的? --不是我啊
啊,不是?那你說是誰的?---是A的,
A沒有這個啊 -- 那是B的(把東西改裝了一下,寫上了b的名字塞給了B)
對應:
1.+ resolveInstanceMethod:(SEL)sel // 對應實例方法
+ resolveClassMethod:(SEL)sel // 對應類方法
2.- (id)forwardingTargetForSelector:(SEL)aSelector
3.- (void)forwardInvocation:(NSInvocation *)anInvocation
具體用法見Runtime系列(消息轉發)
4.runtime 用于hook等操作
用方法調配技術調試黑盒方法-method swizzling
Method m1 = class_getInstanceMethod([p1 class], @selector(printDZL));
Method m2 = class_getClassMethod([Person class], @selector(printDZ)); method_exchangeImplementations(m1, m2);
這樣就能在自定義的方法里,hook 住黑盒中的代碼
5.swift中的runtime
以下是一些結論:
- swift原生類沒有runtime特性,純Swift類的函數調用已經不再是OC的運行時發消息objc_msgsend,而是類似C++的vtable,在編譯時就確定了調用什么函數,所以runtime獲取不到,而繼承NS0bject的類有
- 繼承NS0bject的類如果返回值帶有tuple等swift特性,則剛方法也失去動態派發
- @objc是用來將Swift的API導出給OC與OC runtime使用的,如果你繼承NSObject的類,將會被自動的加入這個標識??梢栽谠鷖wift類里加上這個關鍵字賦予runtime特性
- 加了@objc標識的方法、屬性都無法保證都會被運行時調用,因為Swift會做靜態優化。所以非cocoa的原生方法,沒辦法保證動態派發特性,有可能會被靜態優化,為了防止這種情況,可以在方法、屬性前加上dynamic關鍵字
以上結論的詳細解釋見:Swift Runtime