runtime 運(yùn)行時(shí) 使用

一、消息機(jī)制
頭文件 :<objc/message.h>
設(shè)置:【build Setting】 搜 @“msg” -> Enable strict checking of objc_msgSend calls 設(shè)置 NO


image.png

例 : 創(chuàng)建一個(gè)類,調(diào)用方法
OC: Person * p = [[Person alloc] init];
調(diào)用方法一: [p miao];
調(diào)用方法二: [p performSelector:@selector(miao)];

msg: Person * p = [[Person alloc] init];
objc_msgSend(p,@selector(miao));
so: Person * p = [[Person alloc] init] 可以寫成
Person * p = objc_msgSend(Person.class, @selector(alloc));
p = objc_msgSend(p, @selector(init));
完全C語(yǔ)言寫法 :
Person * p = objc_msgSend(objc_getClass("Person"), sel_registerName("alloc"));
p = objc_msgSend(p, @selector(init));
其中 Person.class -> objc_getClass("Person")
@selector(alloc) -> sel_registerName("alloc")

補(bǔ)充: 編譯器會(huì)根據(jù)情況在 objc_msgSend,objc_msgSend_stret,objc_msgSendSuper,objc_msgSendSuper_stret 或 objc_msgSend_fpret 五個(gè)方法中選擇一個(gè)來調(diào)用。如果消息是傳遞給超類,那么會(huì)調(diào)用 objc_msgSendSuper 方法,如果消息返回值是數(shù)據(jù)結(jié)構(gòu),就會(huì)調(diào)用 objc_msgSendSuper_stret 方法,如果返回值是浮點(diǎn)數(shù),則調(diào)用 objc_msgSend_fpret 方法。

image.png

當(dāng)調(diào)用 [super class] 時(shí),會(huì)轉(zhuǎn)換成 objc_msgSendSuper 函數(shù):

第一步先構(gòu)造 objc_super 結(jié)構(gòu)體,結(jié)構(gòu)體第一個(gè)成員就是 self。第二個(gè)成員是 (id)class_getSuperclass(objc_getClass(“Son”)).
第二步是去 Father 這個(gè)類里去找 - (Class)class,沒有,然后去 NSObject 類去找,找到了。最后內(nèi)部是使用 objc_msgSend(objc_super->receiver, @selector(class)) 去調(diào)用,此時(shí)已經(jīng)和 [self class] 調(diào)用相同了,所以兩個(gè)輸出結(jié)果都是 Son。

二、runtime 運(yùn)用
頭文件: <objc/runtime.h> 注: <objc/message.h> 包含 <objc/runtime.h>,只用 <objc/message.h> 即可

1、獲取某個(gè)類屬性列表
//屬性個(gè)數(shù) 其中.m 中的屬性 也可以拿到
unsigned int count = 0;
// copy new creat 代表毀在 堆區(qū) (Malloc) 開辟空間
// Ivar 成員屬性
Ivar * list = class_copyIvarList(Person.class, &count);
for (int i = 0; i < count ; i++) {
Ivar ivar = list[i];
//通過 Ivar 拿到屬性名稱
const char * name = ivar_getName(ivar);
NSString * key = [NSString stringWithUTF8String:name];
}
//防止內(nèi)存溢出
free(list);

2、給一個(gè)類動(dòng)態(tài)添加新方法
方法: class_addMethod(<#Class _Nullable __unsafe_unretained cls#>, <#SEL _Nonnull name#>, <#IMP _Nonnull imp#>, <#const char * _Nullable types#>)
參數(shù)說明:
Class: 你要添加新方法的那個(gè)類
SEL name : 要添加的方法
IMP : 指向?qū)崿F(xiàn)方法的指針 就是要添加的方法的實(shí)現(xiàn)部分
types: 要添加的方法的返回值和參數(shù) 集體參照官方文檔

在OC中找不到對(duì)相應(yīng)的實(shí)現(xiàn)方法時(shí) 有補(bǔ)救機(jī)制 即 會(huì)先調(diào)用動(dòng)態(tài)決議方法 該方法解決不了問題 再調(diào)用重定向方法 都解決不了問題是 crash
動(dòng)態(tài)決議方法:


image.png

重定向方法:


image.png
image.png

補(bǔ)充:為什么 能在 方法中調(diào)到 self ?只因?yàn)樗顷P(guān)鍵字?
說明:
OC: void mou(id self , SEL _cmd) ,其中 self,_cmd.默認(rèn)隱藏
C: objc_msgSend(object_getClass("Person"), sel_registerName("mou"))
其中:self 對(duì)應(yīng) Person _cmd 對(duì)應(yīng) sel_registerName("mou")

3.把一個(gè)對(duì)象與另外一個(gè)對(duì)象進(jìn)行關(guān)聯(lián)
objc_setAssociatedObject來把一個(gè)對(duì)象與另外一個(gè)對(duì)象進(jìn)行關(guān)聯(lián)。該函數(shù)需要四個(gè)參數(shù):源對(duì)象,關(guān)鍵字,關(guān)聯(lián)的對(duì)象和一個(gè)關(guān)聯(lián)策略


image.png

關(guān)鍵字是一個(gè)void類型的指針。每一個(gè)關(guān)聯(lián)的關(guān)鍵字必須是唯一的。通常都是會(huì)采用靜態(tài)變量來作為關(guān)鍵字。

關(guān)聯(lián)策略表明了相關(guān)的對(duì)象是通過賦值,保留引用還是復(fù)制的方式進(jìn)行關(guān)聯(lián)的;還有這種關(guān)聯(lián)是原子的還是非原子的。這里的關(guān)聯(lián)策略和聲明屬性時(shí)的很類似。這種關(guān)聯(lián)策略是通過使用預(yù)先定義好的常量來表示的。


image.png

image.png

斷開連接:
斷開關(guān)聯(lián)是使用objc_setAssociatedObject函數(shù),傳入nil值即可。
使用函數(shù)objc_removeAssociatedObjects可以斷開所有關(guān)聯(lián)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 2,082評(píng)論 0 9
  • 引導(dǎo) 對(duì)于從事 iOS 開發(fā)人員來說,所有的人都會(huì)答出「 Runtime 是運(yùn)行時(shí) 」,什么情況下用 Runtim...
    Winny_園球閱讀 4,320評(píng)論 3 75
  • 本文分為4個(gè)部分 1.介紹OC和C語(yǔ)言之間的轉(zhuǎn)換 2.介紹運(yùn)行時(shí)和相關(guān)術(shù)語(yǔ) 3.介紹消息發(fā)送機(jī)制已及怎樣找到函數(shù)實(shí)...
    一片楓葉隨風(fēng)舞閱讀 398評(píng)論 0 1
  • 對(duì)于從事 iOS 開發(fā)人員來說,所有的人都會(huì)答出【runtime 是運(yùn)行時(shí)】什么情況下用runtime?大部分人能...
    夢(mèng)夜繁星閱讀 3,812評(píng)論 7 64
  • 仿佛是那只列寧誠(chéng)實(shí)的灰雀/ 它撲騰地掠起/ 在攝像師和捕魚的小孩面前/ 跳了一支草原上的風(fēng)和羊群/ 此刻的晨曦/ ...
    孟章君閱讀 153評(píng)論 0 0

友情鏈接更多精彩內(nèi)容