前言:
- 本文將陸續(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 這個類并不存在)

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_getName 和 sel_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)行說明。