之前沒怎么注意Runtime,最近花了點時間學(xué)習(xí)了下Runtime。雖然網(wǎng)上的資料很多懂算,但是自己總結(jié)一下也是蠻好的只冻。
一,什么是Runtime
runtime即運行時计技,是一套純C的API,而Objective-C就是運行時機制的喜德,其中最主要的就是消息機制。
??Objective-C是基于C的垮媒,它為C添加了面向?qū)ο蟮奶匦陨崦酢:芊旱恼f,C+Runtime = Objective-C睡雇,可以說Runtime是我們 Objective-C幕后工作者萌衬。
??我們都知道在編譯的時候C語言調(diào)用了未實現(xiàn)的函數(shù)就會報錯;而OC中只要聲明了就不會報錯它抱,只有當(dāng)運行的時候才會報錯秕豫,這是因為OC是運行時動態(tài)調(diào)用的。
二抗愁,Runtime的作用
要想使用runtime馁蒂,必須要導(dǎo)入頭文件呵晚,runtime.h
??方法發(fā)送消息的本質(zhì)是讓對象發(fā)送消息,可以通過objc_msgSend讓對象發(fā)送消息沫屡。
runtime 用來干什么呢饵隙??用在那些地方呢沮脖?怎么用呢金矛?
首先要導(dǎo)入頭文件#import <objc/message.h>,其實導(dǎo)入runtime也是可以的勺届,但是message中導(dǎo)入了runtime驶俊,所以我們可以直接導(dǎo)入message。
??我們所寫的OC代碼免姿,Xcode最終會將其編譯成一份C++文件饼酿,生成.opp文件。通過指令 clong -rewrite-objc main.m就會把main.m生成最終代碼胚膊,它會幫我們做很多的事情故俐,這里沒深入進(jìn)去。
??如果說方法發(fā)送消息的本質(zhì)是讓對象發(fā)送消息的話紊婉,我們可以用底層的方法來實現(xiàn)方法發(fā)送消息药版。
??但是當(dāng)我們使用objc_msgSend方法的時候發(fā)現(xiàn),被蘋果給注釋掉了喻犁,這里我們可以在配置里面設(shè)置槽片,將其選擇為NO,然后我們就可以使用消息機制了肢础,如下圖还栓。
執(zhí)行方法
#假設(shè)有一個學(xué)生Student類
Student *student = [Student alloc] init];
runtime: objc_msgSend(student, @selector(sayHello));
OC: [self sayHello];
在程序運行過程中, 動態(tài)地為某個類添加屬性或方法, 修改屬性值或方法 遍歷一個類的所有成員變量(屬性)所有方法
例如:我們需要對一個類的屬性進(jìn)行歸檔解檔的時候?qū)傩蕴貏e的多,這時候乔妈,我們就會寫很多對應(yīng)的代碼蝙云,但是如果使用了runtime就可以動態(tài)設(shè)置氓皱!
查詢類成員變量及類型
/**
* 必備常識:
* Ivar : 成員變量 如果要是動態(tài)創(chuàng)建/修改/查看屬性路召,可以使用Ivar
* Method : 成員方法 如果要是動態(tài)創(chuàng)建/修改/查看方法,可以使用Method
* 下面的例子教大家一些runtime簡單的 查看類中屬性和方法以及動態(tài)添加屬性和方法和修改屬性.
*/
/**
* 通過類的名字來獲取類里面包含的所有屬性
*
* @param className 類名(egs:UIView)
*/
- (void)getIvarsNameListWithClassName:(NSString *)className
{
//通過類的名字獲取到類(egs:通過"學(xué)生"這個類的名字找到"學(xué)生"這個類)
Class ClassName = NSClassFromString(className);
//定義一個變量來存放遍歷出來類里面屬性的個數(shù)
unsigned int outConut = 0;
//查取類里面所有的屬性
Ivar * vars = class_copyIvarList([ClassName class], &outConut);
//打印類里面有多少個屬性
NSLog(@"%d",outConut);
//遍歷類里面所有的屬性 和 屬性類型
for (int i = 0; i < outConut; i ++) {
//獲取類里面屬性的名字(將IVar變量轉(zhuǎn)化為字符串)
const char * ivarName = ivar_getName(vars[i]);
//獲取類里面屬性的類型(獲取IVar的類型)
const char * ivarType = ivar_getTypeEncoding(vars[i]);
//打印屬性的名字和類型
printf("屬性名字:%s 屬性類型:%s\n",ivarName,ivarType);
}
查詢類方法名及類型
/**
* 通過類的名字,查看類中所有的方法
*
* @param className 類的名字(egs:UIView)
*/
- (void)getMethodNameListWithClassName:(NSString *)className
{
//如果想添加方法直接調(diào)用就行了(只需要改一下類)
//添加方法
[self addMethod];
/**
* class_copyMethodList:獲取所有方法
* method_getName:讀取一個Method類型的變量波材,輸出我們在上層中很熟悉的SEL
*
*/
//通過類的名字,獲取到類
Class ClassName = NSClassFromString(className);
//定義一個變量來存放遍歷出來類里面屬性的個數(shù)
unsigned int count = 0;
//查取類里面所有的屬性
Method * method = class_copyMethodList(ClassName, &count);
//遍歷類里面所有的屬性 和 屬性類型
for (int i = 0; i < count; i ++) {
//獲取類里面方法的名字
SEL methodName = method_getName(method[i]);
//獲取類里面方法的類型
const char * methodType = method_copyReturnType(method[i]);
NSLog(@"方法名字:%@,方法類型:%s",NSStringFromSelector(methodName),methodType);
}
}
如有雷同股淡,你就是抄我的!?????? --大展