Objective-C做为一种动态消息型语言,其机制不一样于Java,C#等编译型语言.
它将数据类型的肯定等工做推迟到了运行时期来执行,而且它调用方法的方式实质是像对象发送消息,根据selector在对象的本类以及父类中的方法列表进行查找,若是都找不到就会启动消息转发机制.atom
回到正题,这个话题我想谈下OC的单继承原则.
OC确实是只能单继承的语言,可是基于运行时的机制,却有一种方法让它来实现一下"伪多继承".就是利用NSProxy这个类.spa
NSProxy是和NSObject同级的一个类,能够说它是一个虚拟类,它只是实现了<NSObject>的协议.它的做用有点相似于一个复制类,有人曾经笑谈它是复制操做,想一想其实也挺贴切的,其实原理确实如此.code
工做原理:
用一个继承于NSProxy的子类,在它内部实现一些方法,暴露一个公开方法transform,这个方法是使它变身的关键.而后它变身以后能够对那些对象发送消息,而且能够在内部拦截消息的内容并修改.
能够说,NSProxy几乎能够变身成为任何对象.orm
//JanProxy.h #import <Foundation/Foundation.h> @interface JanProxy : NSProxy - (void)transformObjc:(NSObject *)objc; @end
//JanProxy.m #import "JanProxy.h" @interface JanProxy () @property(nonatomic,strong)NSObject *objc; @end @implementation JanProxy - (void)transformObjc:(NSObject *)objc { //复制对象 self.objc = objc; } //2.有了方法签名以后就会调用方法实现 - (void)forwardInvocation:(NSInvocation *)invocation { if (self.objc) { //拦截方法的执行者为复制的对象 [invocation setTarget:self.objc]; if ([self.objc isKindOfClass:[NSClassFromString(@"Cat") class]]) { //拦截参数 Argument:表示的是方法的参数 index:表示的是方法参数的下标 NSString *str = @"拦截消息"; [invocation setArgument:&str atIndex:2]; } //开始调用方法 [invocation invoke]; } } //1.查询该方法的方法签名 - (NSMethodSignature *)methodSignatureForSelector:(SEL)sel { NSMethodSignature *signature = nil; if ([self.objc methodSignatureForSelector:sel]) { signature = [self.objc methodSignatureForSelector:sel]; } else { signature = [super methodSignatureForSelector:sel]; } return signature; } @end
使用方法对象
Dog *dog = [[Dog alloc]init]; //OC中方法的调用本质上是给这个对象发送一个消息 Cat *cat = [[Cat alloc] init]; //开始复制拦截方法 JanProxy *proxy = [JanProxy alloc]; //开始变身成猫 [proxy transformObjc:cat]; //开始调猫的方法 [proxy performSelector:@selector(eat:) withObject:@"猫发出消息"]; //开始变身成狗 [proxy transformObjc:Dog]; //开始调用学生的方法 [proxy performSelector:@selector(shut)];
最后的结果继承
发现没有,猫发出消息已经被子类的内部拦截而且作出了修改.rem
OC中存在这么一个默默无闻的类NSProxy,填补了"多继承"这个空白区.get