runtime顾名思义,运行时机制。
oc底层都是C语言实现的,oc编译的时候会把自己的代码搞成C代码,然后运行。
而runtime就是OC和C的桥梁。
其实简单的说,runtime就是一套C语言库~
举个简单的例子:利用runtime给model属性赋值(这部分代码,oc中可以一两句代码实现,这里只是说明runtime的简单应用)。
下面是代码:
创建一个继承自NSObject的类名字叫做SetModel,我从里面声明了一个方法,这个方法要求传入一个模型类,并传入要赋值给模型类的字典。
(这是我们最常见的model赋值模式了)
代码如下:
.h文件内容
#import <Foundation/Foundation.h>
@interface SetModel : NSObject
//返回赋值后类的实例;传入参数为类名和一个字典
//注意:这里的赋值需要类的属性名称和dic中key的名称是一样的,否则赋值会失败
+(id)setValueForClass:(Class)cls withDictionary:(NSDictionary *)dic;
@end
.m文件内容
#import "SetModel.h"
#import "objc/runtime.h"
#import "objc/message.h"
@implementation SetModel
//给model属性赋值
+(id)setValueForClass:(Class)cls withDictionary:(NSDictionary *)dic
{
id model = [[cls alloc] init];
if (model)
{
unsigned int count = 0;
//获取类的属性列表
Ivar *ivars = class_copyIvarList(cls, &count);
//给属性赋值
for (int i = 0; i<count; i++)
{
Ivar ivar = ivars[i];
//获取变量名称
const char *name = ivar_getName(ivar);
NSString *key = [NSString stringWithUTF8String:name];
//生成setter方法
NSString *usefullStr = [key substringFromIndex:1]; //跳过下划线
key = usefullStr.capitalizedString; //大写首字母
key = [NSString stringWithFormat:@"set%@:", key]; //拼接set方法字符串
SEL setSel = NSSelectorFromString(key);
//调用setter方法
if ([model respondsToSelector:setSel])
{
id value = @"";
if ([dic objectForKey:usefullStr]!=nil) {
value = [dic objectForKey:usefullStr];
}
[model performSelectorOnMainThread:setSel withObject:value waitUntilDone:[NSThread isMainThread]];
}
}
free(ivars);
}
return model;
}
@end
runtime的用途很多,这是简单的例子。