runtime介绍
runtime从字面上的意思理解就是运行时间,run(跑,运行)time(时间),在iOS中呢俗称运行时,它是一套底层的纯C语言API,属于一个C语言库,包含了很多底层的C语言API,同时它也是OC的幕后工作者,我们平时写的OC代码在运行的过程中都会转为runtime的C语言代码。
runtime的作用
注意哦:用到runtime的地方要导入头文件:objc/runtime.h
作用1:获取一个类全部的成员变量名(私有成员变量也可以获取到滴哦)
我们新建一个Person类,.h代码如下:
#import <Foundation/Foundation.h>
/**
* Person类协议
*/
@protocol PersonDelegate <NSObject>
- (void) PersonDelegateToWork;
@end
@interface Person : NSObject
#pragma mark - 属性
@property (nonatomic,strong) NSString *name; //姓名
@property (nonatomic,strong) NSString *sex; //性别
@property (nonatomic,assign) NSInteger age; //年龄
#pragma mark - 方法
- (void) eat;
- (void) work;
- (void) sleep;
@end
这些成员变量都是共有的,同时在.m文件中我们添加私有属性NSString *job,下面看测试代码:
/**
* 获取一个类的全部成员变量
*/
- (void) getObjcAllIvars{
unsigned int count = 0;
//获取成员变量的结构体
Ivar *ivars = class_copyIvarList([Person class], &count);
for (int i = 0; i < count; i++) {
//获取成员变量的名称,获取到的都为C字符串
const char *name = ivar_getName(ivars[i]);
//C字符串专为OC字符串
NSString *OC_name = [NSString stringWithUTF8String:name];
NSLog(@"i:%d ---- name:%@",i,OC_name);
}
//因为ivars不属于OC对象,所以要记得释放
free(ivars);
}
打印结果:
如上我们看到结果中不仅打印出了公有成员变量,同时私有成员变量也打印了出来。
作用2 同理,我们可以获取到一个类的全部属性名
/**
* 获取一个类的全部属性名称
*/
- (void) getObjcAllProperties{
unsigned int count = 0;
objc_property_t *properties = class_copyPropertyList([Person class], &count);
for (int i = 0; i < count; i++) {
//获取属性名称(C字符串)
const char *name = property_getName(properties[i]);
NSString *OC_name = [NSString stringWithUTF8String:name];
NSLog(@"i:%d --- propertyName:%@",i,OC_name);
}
//非OC对象,记得释放
free(properties);
}
打印结果:
作用3 获取一个类的全部方法
/**
* 获取一个类的全部方法
*/
- (void) getObjcAllMethod{
unsigned int count = 0;
//获取指向改类所有方法的指针
Method *methods = class_copyMethodList([Person class], &count);
for (int i = 0; i < count; i++) {
//获取方法
SEL method = method_getName(methods[i]);
//获取方法名字(C字符串)
const char *name = sel_getName(method);
NSString *methodName = [NSString stringWithUTF8String:name];
//获取方法参数个数
int arguments = method_getNumberOfArguments(methods[i]);
NSLog(@"i:%d ---- methodName:%@ --- arguments:%d",i,methodName,arguments);
}
//释放
free(methods);
}
打印结果:
作用4 获取一个类遵循的所有协议
使当前viewcontroller遵守Person类的协议
/**
* 获取一个类遵循的全部协议
*/
- (void) getObjcAllProtocol{
unsigned int count = 0;
//获取指向改类遵循的所有协议的指针
__unsafe_unretained Protocol **protocols = class_copyProtocolList([self class], &count);
for (int i = 0 ; i < count; i++) {
//获取改类遵循的一个协议指针
Protocol *protocol = protocols[i];
//获取C字符串协议名字
const char *name = protocol_getName(protocol);
NSString *OCProtocolName =[NSString stringWithUTF8String:name];
NSLog(@"i:%d --- protocolName:%@",i ,OCProtocolName);
}
//释放
free(protocols);
}
打印结果:
作用5 利用runtime 归档解档
-(void)encodeWithCoder:(NSCoder *)aCoder{
unsigned int count = 0;
//获得指向当前类的一个属性的指针
objc_property_t *properties = class_copyPropertyList([self class], &count);
for (int i = 0 ; i < count; i++) {
//获取指向当前类的一个属性的指针
objc_property_t property = properties[i];
//获取C字符串属性名
const char *name = property_getName(property);
NSString *propertyName = [NSString stringWithUTF8String:name];
NSString *propertyValue = [self valueForKey:propertyName];
//编码属性
[aCoder encodeObject:propertyValue forKey:propertyName];
}
//记得释放
free(properties);
}
-(instancetype)initWithCoder:(NSCoder *)aDecoder{
unsigned int count = 0;
//获取指向当前类的所有属性的指针
objc_property_t *properties = class_copyPropertyList([self class], &count);
for (int i = 0 ; i < count; i++) {
//获取指向当前类的一个属性的指针
objc_property_t property = properties[i];
const char *name = property_getName(property);
NSString *propertyName = [NSString stringWithUTF8String:name];
//解码属性值
NSString *propertyValue = [aDecoder decodeObjectForKey:propertyName];
[self setValue:propertyValue forKey:propertyName];
}
//释放
free(properties);
return self;
}
/**
* 归档/解档
*/
- (void) deCode{
Person *person = [[Person alloc] init];
person.name = @"王五";
person.sex = @"男";
person.age = 20;
NSString *path = [NSString stringWithFormat:@"%@/archive",NSHomeDirectory()];
[NSKeyedArchiver archiveRootObject:person toFile:path];
Person *unarchivePerson = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
NSLog(@"unarchivePerson:%@",unarchivePerson);
}
打印结果:
其实runtime的作用有太多太多了,今天就先给大家分享到这了。
源码请戳这里runtime简单使用