runtime使用篇: 简单函数的集合

前言:
  • 本文将陆续列举介绍中声明的比较简单的函数,相对复杂的仍然会单独成篇
    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)

判断传入的参数是不是一个类(或元类)
代码示例如下:

// 获取字符串的类
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);

打印结果如下:(其中object_getClass函数的使用见这篇)

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

获取传入参数的类的名称,返回的是C语言字符串类型
代码示例如下:

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

打印结果如下:

runtime[43889:4509715] NSObject

说明:我们平时常用的是以下两种方法

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

打印结果和用object_getClassName函数所获取的相同

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));

打印结果如下:

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));

打印结果如下:

runtime[52100:5537089] NSObject

class_isMetaClass 函数验证可知获得的是元类:

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

通过传入的字符串获取类,如果不存在名为该字符串的类则返回nil

说明:此函数与序号3 objc_getClass 函数使用方法完全相同,作用也基本相同,不同的地方在于:当一个类还没有被注册时, objc_getClass 函数会调用类的回调然后再次检查这个类是否被注册,而 objc_lookUpClass 函数不会调用回调。

6. Class objc_getRequiredClass(const char *name)

通过传入的字符串获取类。

说明:此函数与序号3 objc_getClass 函数使用方法完全相同,作用也基本相同,不同的地方在于:如果不存在名为该字符串的类则杀掉进程从而crash。

如下图:(其中 SubObject 这个类并不存在)

objc_getRequiredClass获取不存在的类会导致crash

7. const char *class_getName(Class cls)

获取传入的类的名称,返回的是C语言字符串类型
代码示例如下:

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

打印结果如下:

runtime[54133:5665180] UITableView

说明:我们平时常用的是以下两种方法

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

打印结果和用 class_getName 函数所获取的相同

8. Class class_getSuperclass(Class cls)

获取传入的类的父类
代码示例如下:

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

打印结果如下:

runtime[54291:5672706] UIResponder

说明:我们平时常用的是以下方法获取父类

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

int class_getVersion(Class cls) :获取类的版本号,默认都是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);

打印结果如下:

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

获取参数 cls 类的变量名为 name 的变量
目前已知的类的变量名只有一个 isa,返回值是参数 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);

打印结果如下:

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

至于为什么没有与之对应的名为 class_setClassVariable 的函数,见苹果回复的邮件。

11. Method class_getInstanceMethod(Class cls, SEL name)

获取 cls 类的名为 name 的实例方法。如果参数 name 传入 cls 类的类方法则返回空,传入其他类的方法也返回空。
代码示例如下:其中 method_getNamesel_getName 函数的作用是获取方法名称

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));

打印结果如下:

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

获取 cls 类的名为 name 的类方法。如果参数 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));

打印结果如下:

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

获取 cls 类的名为 name 方法的实现
代码示例如下:

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

具体使用场景将在介绍动态添加方法时再进行说明。

你可能感兴趣的:(runtime使用篇: 简单函数的集合)