1.存放自定義數(shù)據(jù)
數(shù)據(jù)管理三把劍:
get、set、remove 允懂,用key 來作為存取數(shù)據(jù)的憑證
2.類的方法動態(tài)實現(xiàn)機(jī)制
方法存儲:
選擇子,oc對象的方法可視為簡單c函數(shù)纺讲,原型:
<return type>Class_selector(id self, SEL _cmd,...)
方法維護(hù):
快速緩存表:存儲選擇子和方法的對應(yīng)關(guān)系
方法調(diào)用:
objc_msgsend(some object,@selector(),parameters)去查找快速緩存表,涉及到消息轉(zhuǎn)發(fā)
3.消息轉(zhuǎn)發(fā)機(jī)制:(message forwarding)
三步分別是:說囤屹,這個是不是你的熬甚? --不是我啊
啊,不是肋坚?那你說是誰的乡括?---是A的,
A沒有這個啊 -- 那是B的(把東西改裝了一下智厌,寫上了b的名字塞給了B)
對應(yīng):
1.+ resolveInstanceMethod:(SEL)sel // 對應(yīng)實例方法
+ resolveClassMethod:(SEL)sel // 對應(yīng)類方法
2.- (id)forwardingTargetForSelector:(SEL)aSelector
3.- (void)forwardInvocation:(NSInvocation *)anInvocation
具體用法見Runtime系列(消息轉(zhuǎn)發(fā))
4.runtime 用于hook等操作
用方法調(diào)配技術(shù)調(diào)試黑盒方法-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
以下是一些結(jié)論:
- swift原生類沒有runtime特性,純Swift類的函數(shù)調(diào)用已經(jīng)不再是OC的運行時發(fā)消息objc_msgsend铣鹏,而是類似C++的vtable敷扫,在編譯時就確定了調(diào)用什么函數(shù),所以runtime獲取不到诚卸,而繼承NS0bject的類有
- 繼承NS0bject的類如果返回值帶有tuple等swift特性葵第,則剛方法也失去動態(tài)派發(fā)
- @objc是用來將Swift的API導(dǎo)出給OC與OC runtime使用的,如果你繼承NSObject的類惨险,將會被自動的加入這個標(biāo)識羹幸。可以在原生swift類里加上這個關(guān)鍵字賦予runtime特性
- 加了@objc標(biāo)識的方法辫愉、屬性都無法保證都會被運行時調(diào)用栅受,因為Swift會做靜態(tài)優(yōu)化。所以非cocoa的原生方法恭朗,沒辦法保證動態(tài)派發(fā)特性屏镊,有可能會被靜態(tài)優(yōu)化,為了防止這種情況痰腮,可以在方法而芥、屬性前加上dynamic關(guān)鍵字
以上結(jié)論的詳細(xì)解釋見:Swift Runtime