1.存放自定義數(shù)據(jù)
數(shù)據(jù)管理三把劍:
get、set、remove ,用key 來(lái)作為存取數(shù)據(jù)的憑證
2.類的方法動(dòng)態(tài)實(shí)現(xiàn)機(jī)制
方法存儲(chǔ):
選擇子,oc對(duì)象的方法可視為簡(jiǎn)單c函數(shù),原型:
<return type>Class_selector(id self, SEL _cmd,...)
方法維護(hù):
快速緩存表:存儲(chǔ)選擇子和方法的對(duì)應(yīng)關(guān)系
方法調(diào)用:
objc_msgsend(some object,@selector(),parameters)去查找快速緩存表,涉及到消息轉(zhuǎn)發(fā)
3.消息轉(zhuǎn)發(fā)機(jī)制:(message forwarding)
三步分別是:說(shuō),這個(gè)是不是你的? --不是我啊
啊,不是?那你說(shuō)是誰(shuí)的?---是A的,
A沒(méi)有這個(gè)啊 -- 那是B的(把東西改裝了一下,寫上了b的名字塞給了B)
對(duì)應(yīng):
1.+ resolveInstanceMethod:(SEL)sel // 對(duì)應(yīng)實(shí)例方法
+ resolveClassMethod:(SEL)sel // 對(duì)應(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原生類沒(méi)有runtime特性,純Swift類的函數(shù)調(diào)用已經(jīng)不再是OC的運(yùn)行時(shí)發(fā)消息objc_msgsend,而是類似C++的vtable,在編譯時(shí)就確定了調(diào)用什么函數(shù),所以runtime獲取不到,而繼承NS0bject的類有
- 繼承NS0bject的類如果返回值帶有tuple等swift特性,則剛方法也失去動(dòng)態(tài)派發(fā)
- @objc是用來(lái)將Swift的API導(dǎo)出給OC與OC runtime使用的,如果你繼承NSObject的類,將會(huì)被自動(dòng)的加入這個(gè)標(biāo)識(shí)。可以在原生swift類里加上這個(gè)關(guān)鍵字賦予runtime特性
- 加了@objc標(biāo)識(shí)的方法、屬性都無(wú)法保證都會(huì)被運(yùn)行時(shí)調(diào)用,因?yàn)镾wift會(huì)做靜態(tài)優(yōu)化。所以非cocoa的原生方法,沒(méi)辦法保證動(dòng)態(tài)派發(fā)特性,有可能會(huì)被靜態(tài)優(yōu)化,為了防止這種情況,可以在方法、屬性前加上dynamic關(guān)鍵字
以上結(jié)論的詳細(xì)解釋見:Swift Runtime