RunTime

之前沒怎么注意Runtime,最近花了點時間學習了下Runtime。雖然網(wǎng)上的資料很多,但是自己總結(jié)一下也是蠻好的。

一,什么是Runtime

runtime即運行時,是一套純C的API,而Objective-C就是運行時機制的,其中最主要的就是消息機制。
??Objective-C是基于C的,它為C添加了面向?qū)ο蟮奶匦?。很泛的說,C+Runtime = Objective-C,可以說Runtime是我們 Objective-C幕后工作者。
??我們都知道在編譯的時候C語言調(diào)用了未實現(xiàn)的函數(shù)就會報錯;而OC中只要聲明了就不會報錯,只有當運行的時候才會報錯,這是因為OC是運行時動態(tài)調(diào)用的。

二,Runtime的作用

要想使用runtime,必須要導入頭文件,runtime.h
??方法發(fā)送消息的本質(zhì)是讓對象發(fā)送消息,可以通過objc_msgSend讓對象發(fā)送消息。
runtime 用來干什么呢??用在那些地方呢?怎么用呢?

首先要導入頭文件#import <objc/message.h>,其實導入runtime也是可以的,但是message中導入了runtime,所以我們可以直接導入message。
??我們所寫的OC代碼,Xcode最終會將其編譯成一份C++文件,生成.opp文件。通過指令 clong -rewrite-objc main.m就會把main.m生成最終代碼,它會幫我們做很多的事情,這里沒深入進去。
??如果說方法發(fā)送消息的本質(zhì)是讓對象發(fā)送消息的話,我們可以用底層的方法來實現(xiàn)方法發(fā)送消息。
??但是當我們使用objc_msgSend方法的時候發(fā)現(xiàn),被蘋果給注釋掉了,這里我們可以在配置里面設(shè)置,將其選擇為NO,然后我們就可以使用消息機制了,如下圖。


執(zhí)行方法

#假設(shè)有一個學生Student類 
Student *student = [Student alloc] init];
runtime:  objc_msgSend(student, @selector(sayHello));
OC: [self sayHello];

在程序運行過程中, 動態(tài)地為某個類添加屬性或方法, 修改屬性值或方法 遍歷一個類的所有成員變量(屬性)所有方法
例如:我們需要對一個類的屬性進行歸檔解檔的時候?qū)傩蕴貏e的多,這時候,我們就會寫很多對應的代碼,但是如果使用了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:通過"學生"這個類的名字找到"學生"這個類)
    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);
    }
    
    
}

如有雷同,你就是抄我的!?????? --大展

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

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

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