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

前言:
  • 本文将陆续列举介绍<objc/runtime.h>中声明的比较简单的函数,相对复杂的仍然会单独成篇
    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] <null selector>
runtime[62633:6415335] <null selector>
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] <null selector>
runtime[62866:6425568] <null selector>
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));

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,542评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,596评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,021评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,682评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,792评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,985评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,107评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,845评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,299评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,612评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,747评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,441评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,072评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,828评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,069评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,545评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,658评论 2 350

推荐阅读更多精彩内容

  • 我们常常会听说 Objective-C 是一门动态语言,那么这个「动态」表现在哪呢?我想最主要的表现就是 Obje...
    Ethan_Struggle阅读 2,186评论 0 7
  • 转至元数据结尾创建: 董潇伟,最新修改于: 十二月 23, 2016 转至元数据起始第一章:isa和Class一....
    40c0490e5268阅读 1,690评论 0 9
  • Objective-C语言是一门动态语言,他将很多静态语言在编译和链接时期做的事情放到了运行时来处理。这种动态语言...
    tigger丨阅读 1,390评论 0 8
  • 原文出处:南峰子的技术博客 Objective-C语言是一门动态语言,它将很多静态语言在编译和链接时期做的事放到了...
    _烩面_阅读 1,222评论 1 5
  • 悄悄的, 我想告诉你, 你是我爱的边缘, 是我恨的藩篱。 悄悄的, 我想告诉你, 我们是天上的织女牛郎, 你闪一下...
    朝夕骏阅读 153评论 0 0