runtime使用篇: 簡單函數(shù)的集合

前言:
  • 本文將陸續(xù)列舉介紹<objc/runtime.h>中聲明的比較簡單的函數(shù),相對復(fù)雜的仍然會單獨成篇
    BOOL object_isClass(id obj)
    const char *object_getClassName(id obj)
    Class objc_getClass(const char *name)
    Class objc_getMetaClass(const char *name)
    BOOL class_isMetaClass(Class cls)
    Class objc_lookUpClass(const char *name)
    Class objc_getRequiredClass(const char *name)
    const char *class_getName(Class cls)
    Class class_getSuperclass(Class cls)
    int class_getVersion(Class cls)
    void class_setVersion(Class cls, int version)
    Ivar class_getClassVariable(Class cls, const char *name)
    Method class_getInstanceMethod(Class cls, SEL name)
    Method class_getClassMethod(Class cls, SEL name)
    IMP class_getMethodImplementation(Class cls, SEL name)
1. BOOL object_isClass(id obj)

判斷傳入的參數(shù)是不是一個類(或元類)
代碼示例如下:

// 獲取字符串的類
Class stringClass = [@"ab" class];
BOOL isClass1 = object_isClass(stringClass);
NSLog(@"%d", isClass1);

// 獲取NSObject的元類
Class nsobjectClass = object_getClass([NSObject class]);
BOOL isClass2 = object_isClass(nsobjectClass);
NSLog(@"%d", isClass2);

打印結(jié)果如下:(其中object_getClass函數(shù)的使用見這篇

runtime[43695:4500971] 1
runtime[43695:4500971] 1
2. const char *object_getClassName(id obj)

獲取傳入?yún)?shù)的類的名稱,返回的是C語言字符串類型
代碼示例如下:

NSObject *obj = [[NSObject alloc] init];
const char *className = object_getClassName(obj);
NSLog(@"%s", className);

打印結(jié)果如下:

runtime[43889:4509715] NSObject

說明:我們平時常用的是以下兩種方法

NSLog(@"%@", [obj class]);
NSLog(@"%@", NSStringFromClass([obj class]));

打印結(jié)果和用object_getClassName函數(shù)所獲取的相同

3. Class objc_getClass(const char *name)

通過傳入的字符串獲取類,如果不存在名為該字符串的類則返回nil
代碼示例如下:

Class class1 = objc_getClass("NSString");
Class class2 = objc_getClass("SubObject"); // SubObject這個類并不存在
NSLog(@"%@", NSStringFromClass(class1));
NSLog(@"%@", NSStringFromClass(class2));

打印結(jié)果如下:

runtime[51697:5513088] NSString
runtime[51697:5513088] (null)

說明:我們平時常用的是以下方法

NSClassFromString(@"NSString");
4. Class objc_getMetaClass(const char *name)BOOL class_isMetaClass(Class cls)

objc_getMetaClass :通過傳入的字符串獲取元類,如果不存在名為該字符串的元類則返回nil
class_isMetaClass :判斷傳入的類是不是元類
代碼示例如下:

Class metaClass = objc_getMetaClass("NSObject");
NSLog(@"%@", NSStringFromClass(metaClass));

打印結(jié)果如下:

runtime[52100:5537089] NSObject

class_isMetaClass 函數(shù)驗證可知獲得的是元類:

NSLog(@"%d", class_isMetaClass(metaClass));
5. Class objc_lookUpClass(const char *name)

通過傳入的字符串獲取類,如果不存在名為該字符串的類則返回nil

說明:此函數(shù)與序號3 objc_getClass 函數(shù)使用方法完全相同,作用也基本相同,不同的地方在于:當(dāng)一個類還沒有被注冊時, objc_getClass 函數(shù)會調(diào)用類的回調(diào)然后再次檢查這個類是否被注冊,而 objc_lookUpClass 函數(shù)不會調(diào)用回調(diào)。

6. Class objc_getRequiredClass(const char *name)

通過傳入的字符串獲取類。

說明:此函數(shù)與序號3 objc_getClass 函數(shù)使用方法完全相同,作用也基本相同,不同的地方在于:如果不存在名為該字符串的類則殺掉進(jìn)程從而crash。

如下圖:(其中 SubObject 這個類并不存在)

objc_getRequiredClass獲取不存在的類會導(dǎo)致crash

7. const char *class_getName(Class cls)

獲取傳入的類的名稱,返回的是C語言字符串類型
代碼示例如下:

const char *name = class_getName([UITableView class]);
NSLog(@"%s", name);

打印結(jié)果如下:

runtime[54133:5665180] UITableView

說明:我們平時常用的是以下兩種方法

NSLog(@"%@", [UITableView class]);
NSLog(@"%@", NSStringFromClass([UITableView class]));

打印結(jié)果和用 class_getName 函數(shù)所獲取的相同

8. Class class_getSuperclass(Class cls)

獲取傳入的類的父類
代碼示例如下:

Class superclass = class_getSuperclass([UIView class]);
NSLog(@"%s", class_getName(superclass));

打印結(jié)果如下:

runtime[54291:5672706] UIResponder

說明:我們平時常用的是以下方法獲取父類

[UIView superclass];
9. int class_getVersion(Class cls)void class_setVersion(Class cls, int version)

int class_getVersion(Class cls) :獲取類的版本號,默認(rèn)都是0
void class_setVersion(Class cls, int version) :修改某個類的版本號
代碼示例如下:

int version = class_getVersion([UIColor class]);
NSLog(@"%d", version);

class_setVersion([UIColor class], 10);
int version2 = class_getVersion([UIColor class]);
NSLog(@"%d", version2);

打印結(jié)果如下:

runtime[54751:5693992] 0
runtime[54751:5693992] 10
10. Ivar class_getClassVariable(Class cls, const char *name)

獲取參數(shù) cls 類的變量名為 name 的變量
目前已知的類的變量名只有一個 isa,返回值是參數(shù) cls 的元類。代碼示例如下:

Ivar viewIvar = class_getClassVariable([UIView class], "isa");
id getViewIvar = object_getIvar([UIView class], viewIvar);
NSLog(@"%d", class_isMetaClass(getViewIvar));
NSLog(@"%@", getViewIvar);

Class metaClass = objc_getMetaClass("NSObject");
Ivar ivar = class_getClassVariable(metaClass, "isa");
id getIvar = object_getIvar([NSObject class], ivar);
NSLog(@"%d", class_isMetaClass(getIvar));
NSLog(@"%@", getIvar);

打印結(jié)果如下:

runtime[60570:6123050] 1
runtime[60570:6123050] UIView
runtime[60570:6123050] 1
runtime[60570:6123050] NSObject

至于為什么沒有與之對應(yīng)的名為 class_setClassVariable 的函數(shù),見蘋果回復(fù)的郵件。

11. Method class_getInstanceMethod(Class cls, SEL name)

獲取 cls 類的名為 name 的實例方法。如果參數(shù) name 傳入 cls 類的類方法則返回空,傳入其他類的方法也返回空。
代碼示例如下:其中 method_getNamesel_getName 函數(shù)的作用是獲取方法名稱

Method mth1 = class_getInstanceMethod([UIButton class], @selector(setImage:forState:)); // UIButton 的實例方法
SEL sel1 = method_getName(mth1);
NSLog(@"%s", sel_getName(sel1));

Method mth2 = class_getInstanceMethod([UIButton class], @selector(buttonWithType:)); // UIButton 的類方法
SEL sel2 = method_getName(mth2);
NSLog(@"%s", sel_getName(sel2));

Method mth3 = class_getInstanceMethod([UIButton class], @selector(imageNamed:)); // UIImage 的類方法
SEL sel3 = method_getName(mth3);
NSLog(@"%s", sel_getName(sel3));

打印結(jié)果如下:

runtime[62633:6415335] setImage:forState:
runtime[62633:6415335] <null selector>
runtime[62633:6415335] <null selector>
12. Method class_getClassMethod(Class cls, SEL name)

獲取 cls 類的名為 name 的類方法。如果參數(shù) name 傳入 cls 類的實例方法則返回空,傳入其他類的方法也返回空。
代碼示例如下:

Method mth1 = class_getClassMethod([UIColor class], @selector(colorWithWhite:alpha:)); // UIColor 的類方法
SEL sel1 = method_getName(mth1);
NSLog(@"%s", sel_getName(sel1));

Method mth2 = class_getClassMethod([UIColor class], @selector(initWithWhite:alpha:)); // UIColor 的實例方法
SEL sel2 = method_getName(mth2);
NSLog(@"%s", sel_getName(sel2));

Method mth3 = class_getClassMethod([UIButton class], @selector(imageNamed:)); // UIImage 的類方法
SEL sel3 = method_getName(mth3);
NSLog(@"%s", sel_getName(sel3));

打印結(jié)果如下:

runtime[62866:6425568] colorWithWhite:alpha:
runtime[62866:6425568] <null selector>
runtime[62866:6425568] <null selector>
13. IMP class_getMethodImplementation(Class cls, SEL name)

獲取 cls 類的名為 name 方法的實現(xiàn)
代碼示例如下:

IMP imp = class_getMethodImplementation([UIView class], @selector(animateWithDuration:animations:completion:));
IMP imp2 = class_getMethodImplementation([UIView class], @selector(setNeedsDisplay));

具體使用場景將在介紹動態(tài)添加方法時再進(jìn)行說明。

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

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

  • 我們常常會聽說 Objective-C 是一門動態(tài)語言,那么這個「動態(tài)」表現(xiàn)在哪呢?我想最主要的表現(xiàn)就是 Obje...
    Ethan_Struggle閱讀 2,333評論 0 7
  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 2,051評論 0 9
  • Objective-C語言是一門動態(tài)語言,他將很多靜態(tài)語言在編譯和鏈接時期做的事情放到了運行時來處理。這種動態(tài)語言...
    tigger丨閱讀 1,590評論 0 8
  • 原文出處:南峰子的技術(shù)博客 Objective-C語言是一門動態(tài)語言,它將很多靜態(tài)語言在編譯和鏈接時期做的事放到了...
    _燴面_閱讀 1,415評論 1 5
  • 悄悄的, 我想告訴你, 你是我愛的邊緣, 是我恨的藩籬。 悄悄的, 我想告訴你, 我們是天上的織女牛郎, 你閃一下...
    朝夕駿閱讀 197評論 0 0

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