Runtime 10種實際用法

runtime簡介:

Runtime 又叫運行時,是一套底層的 C 語言 API,其為 iOS 內部的核心之一,我們平時編寫的 OC 代碼,底層都是基于它來實現(xiàn)的。

人在江湖飄,身不由己啊。循環(huán)不停的業(yè)務,都幾乎沒有時間去總結。就是會用一些,但是真正想下runtime這個。自己還真說不出個所以然來。

爬爬帖子,給自己留個印兒。

OC最實用的runtime總結,面試、工作你看我就足夠了!
讓你快速上手Runtime
runtime詳解
詳解runtime運行時機制
萬能控制器跳轉

看一張圖:


image.png

十大用法:

  • 1.將某些OC代碼轉為運行時代碼,探究底層,比如block的實現(xiàn)原理
  • 2.攔截系統(tǒng)自帶的方法調用(Swizzle 黑魔法),也可以說成對系統(tǒng)的方法進行替換,比如攔截imageNamed:、viewDidLoad、alloc
  • 3.實現(xiàn)分類也可以增加屬性;
  • 4.實現(xiàn)NSCoding的自動歸檔和自動解檔;(不用對每個屬性edcode和decode了,如果幾十個屬性一個個的encode和decode真的很麻煩啊,使用運行時可以遍歷出每個對象的屬性,數(shù)組的方式遍歷eccode,decode)
  • 5.實現(xiàn)字典和模型的自動轉換(核心就是可以遍歷出字典中的每個屬性,json解析中大??蚣芏加昧诉@個特性,包括MJEXtension,YYModel,jsonModel都是將json轉換為字典,再遍歷字典中的每個屬性來進行modle的轉換)。
  • 6.動態(tài)增加方法 (動態(tài)的為某個類或對象增加一個方法,摘錄文章中有詳細介紹)
  • 7.動態(tài)變量控制 (動態(tài)對某個對象的變量的值進行替換,摘錄文章有詳細介紹)
  • 8.實現(xiàn)萬能控制器跳轉

產品來一變態(tài)需求,推送過來的消息,要跳轉到任意控制器.利用runtime動態(tài)生成對象、屬性、方法這特性,我們可以先跟服務端商量好,定義跳轉規(guī)則,比如要跳轉到A控制器,需要傳屬性id、type,那么服務端返回字典給我,里面有控制器名,兩個屬性名跟屬性值,客戶端就可以根據(jù)控制器名生成對象,再用kvc給對象賦值,這樣就搞定了。

組件化其實也用到了runtime,根據(jù)url,動態(tài)獲取到類,參數(shù)等??梢詤⒖寄⒐浇珠_源項目

  • 9.插件開發(fā)
  • 10.Jspath 熱更新 也是使用運行時,jspatch 基本上算是黑科技,在線修復版本bug,雖然被蘋果爸爸禁止使用了一段時間,后來好像談妥了,又可以付費使用了。
總結:

綜上所述,runtime核心用法有一下三點。

Method class_getClassMethod(Class cls , SEL name) //獲得某個類的類方法
Method class_getInstanceMethod(Class cls , SEL name) // 獲得某個類的實例對象方法
void method_exchangeImplementations(Method m1 , Method m2) // 交換兩個方法的實現(xiàn)
1、方法簡單的交換

下面通過runtime 實現(xiàn)方法交換,類方法用class_getClassMethod ,對象方法用class_getInstanceMethod

// 獲取兩個類的類方法
Method m1 = class_getClassMethod([Person class], @selector(run));
Method m2 = class_getClassMethod([Person class], @selector(study));
// 開始交換方法實現(xiàn)
method_exchangeImplementations(m1, m2);
// 交換后,先打印學習,再打印跑!
[Person run];
[Person study];
2、攔截系統(tǒng)方法

步驟:
1、為UIImage建一個分類(UIImage+Category)
2、在分類中實現(xiàn)一個自定義方法,方法中寫要在系統(tǒng)方法中加入的語句,比如版本判斷

+ (UIImage *)xh_imageNamed:(NSString *)name {
    double version = [[UIDevice currentDevice].systemVersion doubleValue];
    if (version >= 7.0) {
        // 如果系統(tǒng)版本是7.0以上,使用另外一套文件名結尾是‘_os7’的扁平化圖片
        name = [name stringByAppendingString:@"_os7"];
    }
    return [UIImage xh_imageNamed:name];
}

3、分類中重寫UIImage的load方法,實現(xiàn)方法的交換(只要能讓其執(zhí)行一次方法交換語句,load再合適不過了)

+ (void)load {
    // 獲取兩個類的類方法
    Method m1 = class_getClassMethod([UIImage class], @selector(imageNamed:));
    Method m2 = class_getClassMethod([UIImage class], @selector(xh_imageNamed:));
    // 開始交換方法實現(xiàn)
    method_exchangeImplementations(m1, m2);
}

注意:自定義方法中最后一定要再調用一下系統(tǒng)的方法,讓其有加載圖片的功能,但是由于方法交換,系統(tǒng)的方法名已經變成了我們自定義的方法名(有點繞,就是用我們的名字能調用系統(tǒng)的方法,用系統(tǒng)的名字能調用我們的方法),這就實現(xiàn)了系統(tǒng)方法的攔截!

3、獲得一個類的所有成員變量
Ivar *class_copyIvarList(Class cls , unsigned int *outCount) //獲得一個類的所有成員變量
const char *ivar_getName(Ivar v) //獲得成員變量的名字 
const char *ivar_getTypeEndcoding(Ivar v) //獲得成員變量的類型
//獲取Person類中所有成員變量的名字和類型
unsigned int outCount = 0;
Ivar *ivars = class_copyIvarList([Person class], &outCount);

// 遍歷所有成員變量
for (int i = 0; i < outCount; i++) {
    // 取出i位置對應的成員變量
    Ivar ivar = ivars[i];
    const char *name = ivar_getName(ivar);
    const char *type = ivar_getTypeEncoding(ivar);
    NSLog(@"成員變量名:%s 成員變量類型:%s",name,type);
}
// 注意釋放內存!
free(ivars);

參考文章:
https://blog.csdn.net/qq_30513483/article/details/51312848

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

相關閱讀更多精彩內容

  • 閱讀了多篇運行時的文章,感覺都很不錯,從幾篇文章里面提取一些個人認為比較重要的,偏實戰(zhàn)的知識點的摘錄,另外還結合了...
    wg689閱讀 23,946評論 19 378
  • Runtime 10種用法 閱讀了多篇運行時的文章,感覺都很不錯,從幾篇文章里面提取一些個人認為比較重要的,偏實戰(zhàn)...
    零度_不結冰閱讀 266評論 0 0
  • 對于從事 iOS 開發(fā)人員來說,所有的人都會答出【runtime 是運行時】什么情況下用runtime?大部分人能...
    夢夜繁星閱讀 3,798評論 7 64
  • 引導 對于從事 iOS 開發(fā)人員來說,所有的人都會答出「 Runtime 是運行時 」,什么情況下用 Runtim...
    Winny_園球閱讀 4,306評論 3 75
  • 米哈里·奇克森米哈里提出了心流這個概念,他把它定義為“對所做的事情全身心投入的感受,心流產生的時候,會有高度的興奮...
    每天慌閱讀 529評論 1 2

友情鏈接更多精彩內容