美文网首页
iOS学习笔记:Runtime

iOS学习笔记:Runtime

作者: 木登与木由 | 来源:发表于2017-12-12 14:22 被阅读9次

一、消息发送机制(iOS5.0以后苹果不建议使用,需要设置Bulid Setting的···objc_msgSend Calls)

1、OC动态调用:SEL 方法编号 IMP 方法实现
2、C语言静态调用
3、发送消息:objc_magSend(p,@selector(tip)); 给某个对象 发送某个编号
4、创建一个类,以自定义简化KVO为例:

//动态创建一个子类
    //1、获取类名
    NSString *oldClassName = NSStringFromClass([self class]);
    NSString *newClassName = [@"new" stringByAppendingString:oldClassName];
    //2、创建类
    Class newClass = objc_allocateClassPair([self class], newClassName.UTF8String, 0);
    //3、注册类
    objc_registerClassPair(newClass);
    //4、修改一个类的类型 将self修改为newClass类型
    object_setClass(self, newClass);
    //5、重写(覆盖父类方法,实际为子类添加一个与父类方法相同名字的方法,继承 并不是真正的获得了父类的方法 除非为子类添加方法即面向对象中说的 覆盖) 属性的set方法
    class_addMethod(newClass, @selector(setName:), (IMP)setname, "v@:@");
    //6、绑定对象
    objc_setAssociatedObject(self, (__bridge const void*)@"name1", observer, OBJC_ASSOCIATION_ASSIGN);
    
void setname(id self,SEL _cmd,NSString *newName){
    //保存当前类型
    id class = [self class];
    //修改为父类类型
    object_setClass(self, class_getSuperclass([self class]));
    //给父类发送setName消息
    objc_msgSend(self,@selector(setName:),newName);

    //取出 observer
    id observer = objc_getAssociatedObject(self, (__bridge const void*)@"name1");
    //调用 observer
    objc_msgSend(observer,@selector(observeValueForKeyPath:ofObject:change:context:),@"name",self,@{@"name":newName},nil);
    
    //把类型改回
    object_setClass(self, class);
}

二、Runtime(运行时)- 机制

1、苹果提供了一套比较底层的C语言API #import<objc/runtime.h>
2、有什么用:Runtime是属于OC的底层实现,可以运行一些OC无法实现的非常底层的操作。比如:1)在程序运行的过程中动态的创建一个类:2)在程序运行时动态的为某个类添加修改 属性、方法;3)遍历一个类的所有成员变量以及成员方法

三、Hook 钩子

1、勾住某个类的某个方法,在该方法调用时就能知道,然后做提前写好的相应的处理
2、方法懒加载,即动态添加方法。应用:KVO
3、KVO:使用的类调用addObserver时,1)默认动态创建一个子类2)修改self(调用者)的类型 3)动态添加setName方法

相关文章

网友评论

      本文标题:iOS学习笔记:Runtime

      本文链接:https://www.haomeiwen.com/subject/synubxtx.html