Objective-C Runtime是一個將C語言轉(zhuǎn)化為面向?qū)ο笳Z言的擴展嫡良,Objective-C是基于動態(tài)運行時類型,用Objective-C編寫的程序不能直接編譯成可令機器讀懂的機器語言级乐,也就是說:在程序運行的時候,通過Runtime把程序轉(zhuǎn)為可令機器讀懂的機器語言睹逃。
網(wǎng)上也有很多介紹runtime的文章亚脆,本文介紹runtime在開發(fā)中的相關(guān)使用,旨在讀者能在閱讀本文后并對它有一定的基本了解嘹裂,可以在開發(fā)過程中運用自如妄壶。
常見用法
-
動態(tài)的添加對象的成員變量和方法
-
獲取對象的成員所有的變量,屬性和方法
-
動態(tài)更改某個方法的實現(xiàn)
-
動態(tài)交換兩個方法的實現(xiàn)(Method Swizzling)
-
實現(xiàn)分類也可以添加屬性
-
實現(xiàn)NSCoding的自動歸檔和解檔
-
實現(xiàn)字典轉(zhuǎn)模型的自動轉(zhuǎn)換
部分代碼
void sayFuction(id self, SEL _cmd, id some1,id some2){
NSLog(@"%@歲的%@說:%@", object_getIvar(self, class_getInstanceVariable([self class], "_age")),[self valueForKey:@"name"],some1);
}
-(void)viewDidLoad {
[super viewDidLoad];
//動態(tài)創(chuàng)建對象,創(chuàng)建一個 Person 繼承自 NSObject類
Class People0 = objc_allocateClassPair([NSObject class], "People0", 0);
//添加 NSString *_name 成員變量
class_addIvar(People0, "_name", sizeof(NSString*), log2(sizeof(NSString*)), @encode(NSString*));
//添加 int _age 成員變量
class_addIvar(People0, "_age", sizeof(int), sizeof(int), @encode(int));
//注冊方法名為 say 的方法
SEL s = sel_registerName("say:");
SEL aSel = @selector(movieTitle); //SEL是selector在Objective-C中的表示類型寄狼。Selector 就是oc的virtual table中指向?qū)嶋H執(zhí)行 function pointer的一個C 字符串丁寄;selector可以理解為區(qū)別方法的ID。
//為該類 添加 say 方法
class_addMethod(People0, s, (IMP)sayFuction, "v@:@");/*把C 函數(shù)定義為 IMP 這個type泊愧;IMP 表示方法實現(xiàn)伊磺;最后個參數(shù)表上 方法類型*/
//所有的方法type:http://www.huangyibiao.com/runtime-method-in-detail/
class_addMethod(People0, @selector(say1), (IMP)sayFuction, "V@:@");
//注冊該類
objc_registerClassPair(People0);
//創(chuàng)建一個類的實例
id People0Instance = [[People0 alloc]init];
//kvc
[People0Instance setValue:@"蒼老師" forKey:@"name"]; //注意是 name(跟_name是一樣的)
//從類中獲取成員Ivar
Ivar ageIvar = class_getInstanceVariable(People0, "_age");
//為People0Instance 的成員變量賦值
object_setIvar(People0Instance, ageIvar, @18);
//調(diào)用 People0Instance 對象中的 s 方法選擇器對應(yīng)的方法
((void (*)(id, SEL, id))objc_msgSend)(People0Instance, s, @"大家hao!");
((void (*)(id, SEL, id))objc_msgSend)(People0Instance, @selector(say1), @"大家hao123");
// [People0 say1];
People0Instance = nil;//當People0類或者它的子類的實例還存在删咱,則不能調(diào)用objc_disposeClassPair這個方法屑埋;因此這里要先銷毀實例對象后才能銷毀類;
//銷毀類
objc_disposeClassPair(People0);
}
打印
2016-08-02 10:26:25.361 Objective-C Runtime入門教程[787:21001] 18歲的蒼老師說:大家hao痰滋!
2016-08-02 10:26:25.361 Objective-C Runtime入門教程[787:21001] 18歲的蒼老師說:大家hao123
所有代碼下載地址
https://github.com/NGjiapeche/runtimeDemo/tree/master
不只是不求甚解
RunTime入門教程摘能,強力推薦: Objective-C Runtime 1小時入門教程
RunTime補充: Objective-C特性:Runtime
RunTime補充1: 理解 Objective-C Runtime
RunTime補充2: Objective-C Runtime
RunTime收尾: 刨根問底Objective-C Runtime