博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS | NSProxy
阅读量:5813 次
发布时间:2019-06-18

本文共 2013 字,大约阅读时间需要 6 分钟。

Objective-C作为一种动态消息型语言,其机制不同于Java ,C#等编译型语言.

它将数据类型的确定等工作推迟到了运行时期来执行,并且它调用方法的方式实质是像对象发送消息,根据selector在对象的本类以及父类中的方法列表进行查找,如果都找不到就会启动消息转发机制.

回到正题,这个话题我想谈下OC的单继承原则.

OC确实是只能单继承的语言,但是基于运行时的机制,却有一种方法让它来实现一下"伪多继承".就是利用NSProxy这个类.

NSProxy是和NSObject同级的一个类,可以说它是一个虚拟类,它只是实现了<NSObject>的协议.它的作用有点类似于一个复制类,有人曾经笑谈它是卡卡西的复制忍术,想想其实也挺贴切的,其实原理确实如此.

过程:

用一个继承于NSProxy的子类,在它内部实现一些方法,暴露一个公开方法transform,这个方法是使它变身的关键.然后它变身之后可以对那些对象发送消息,并且可以在内部拦截消息的内容并修改.

可以说,几乎可以变身成为任何对象.

直接上个代码来展示下

JanProxy.h
#import 
@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)];

最后的结果

控制台输出结果

发现没有,猫发出消息已经被子类的内部拦截并且做出了修改.

总结

OC中存在这么一个默默无闻的类NSProxy,填补了"多继承"这个空白区.

转载地址:http://tstbx.baihongyu.com/

你可能感兴趣的文章
【ES6】数值的扩展
查看>>
性能测试之稳定性测试
查看>>
ES6的 Iterator 遍历器
查看>>
2019届高二(下)半期考试题(文科)
查看>>
nginx 301跳转到带www域名方法rewrite(转)
查看>>
AIX 配置vncserver
查看>>
windows下Python 3.x图形图像处理库PIL的安装
查看>>
【IL】IL生成exe的方法
查看>>
network
查看>>
SettingsNotePad++
查看>>
centos7安装cacti-1.0
查看>>
3个概念,入门 Vue 组件开发
查看>>
没有JS的前端:体积更小、速度更快!
查看>>
数据指标/表现度量系统(Performance Measurement System)综述
查看>>
GitHub宣布推出Electron 1.0和Devtron,并将提供无限制的私有代码库
查看>>
Angular2, NativeScript 和 React Native比较[翻译]
查看>>
论模式在领域驱动设计中的重要性
查看>>
国内首例:飞步无人卡车携手中国邮政、德邦投入日常运营
查看>>
微软将停止对 IE 8、9和10的支持
查看>>
微服务架构会和分布式单体架构高度重合吗
查看>>