一、消息发送机制(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方法
网友评论