RunTime简称运行时,是系统在运行的时候的一些机制,其中最主要的是消息机制.
C语言与OC语言的区别:
- 对于C语言:函数的调用在编译的时候会决定调用哪个函数,编译按成之后顺序执行,无任何二义性。
- 对于OC语言:函数的调用成为消息发送.属于动态调用过程.在编译的时候并不能决定真正调用哪个函数.
使用RunTime
拦截系统自带的方法调用:
需要用到的方法:
1. 获得某个类的方法:
`Method class_getClassMethod(Class cls , SEL name)`
2. 获得某个类的实例对象方法
`Method class_getInstanceMethod(Class cls , SEL name)`
3. 交换两个方法的实现:
`void method_exchangeImplementation(Method m1 , Method m2)`
Demo:
创建一个Person类,勒种实现以下两个类方法,并在.文件中声明
`+ (void)run {
NSLog(@"跑");
}
+ (void)study {
NSLog(@"学习");
}`
控制器中调用,则先打印跑,后打印学习
`
[Person run];
[Person study];
`
下面用过runtime实现方法交换,类方法用class_getClassMethod, 对象方法用calss_getInstaceMethod
`
//获取两个类的类方法:
Method m1 = class_getClassMethod([Person class], @selector(run));
Method m2 = class_getClassMethod([Person class], @selector(study));
//开始交换方法实现:
method_exchangeImplmentation(m1 , m2);
//交换后,先打印学习,后打印跑!
[Person run];
[Person study];
`
运行时的归档方法:
`
- (void)encodeWithCoder:(NSCoder *)encoder {
unsigned int count = 0;
Ivar * ivars = class_copyIvarList([Movie class], $count);
for (int i = 0 ;i < count;i++) {
//去除i位置对应的成员变量
Ivar ivar = ivars[i];
//查看成员变量
const char *name = ivar_getName(ivar);
//归档
NSString * key = [self stringWithUTF8String:name];
id value = [self valueForKey:key];
[encoder encodeObject:value forKey:key];
}
free(ivars);
}
-(void)initWithCoder:(NSCoder *)Decoder {
if (self = [super init]){
unsigned int count = 0;
Ivar *ivars = class_copyIvarList([Movie class],$count);
for (int i = 0;i < count;i++){
//取出i位置对应的成员处理
Ivar ivar = ivars[i];
//查看成员变量
const char * name = ivar_getName(ivar);
//归档
NSString * key = [NSString stringWithUTF8String:name];
id vlaue = [decoder decodeObjectForKey:key];
//设置到成员变量身上
[self setValue:value foeKey:key];
}
free(ivars);
}
return self;
}`
参考学习的文章: