RunTime(1)

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;
}`

参考学习的文章: