NSProxy应用例子
动态代理模式的应用很多,特别是在不能修改被代理类的前提下,要对执行某些方法时需要打log或者捕捉异常等处理时,是一个非常方便的方法。只需要少量修改客户端(场景类)代码和添加一个代理类就可以实现,这个符合Open-Close Principle。
在Java和.Net中的AOP也是利用了这种代理模式的实现。
iOS实现的代码如下:
首先,定义一个接口,
@protocol DPDynamicProtocol <NSObject> @required
- (void)doSomething;
- (void)doOtherThing; @end
这个接口做两件事,doSomething和doOtherThing。
被代理类需要实现这个接口(不实现其实也可以,只是设计不好,每一个类都应该实现接口或者继承自一个抽象类)。
#import "DPDynamicProtocol.h" @interface DPNormalObject : NSObject <DPDynamicProtocol> @end
@implementation DPNormalObject
- (void)doSomething {
NSLog(@"normal object do something");
}
- (void)doOtherThing {
NSLog(@"normal object do other thing");
}
@end
同时,代理类也实现DPDynamicProtocal接口,并且继承自NSProxy这个类。
#import "DPDynamicProtocol.h"
@interface DPDynamicProxy : NSProxy <DPDynamicProtocol> {
@private
id<DPDynamicProtocol> _obj;
}
- (id)initWithObject:(id<DPDynamicProtocol>)obj;
@end
@implementation DPDynamicProxy
- (id)initWithObject:(id<DPDynamicProtocol>)obj {
_obj = obj;
return self;
}
- (void)forwardInvocation:(NSInvocation *)invocation {
if (_obj) {
NSLog(@"proxy invocation obj method : %s", [invocation selector]);
[invocation setTarget:_obj];
[invocation invoke];
}
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel {
if ([_obj isKindOfClass:[NSObject class]]) {
return [(NSObject *)_obj methodSignatureForSelector:sel];
}
return [super methodSignatureForSelector:sel];
}
- (void)doSomething {
NSLog(@"proxy do something");//1
[_obj doSomething];
}
@end
这样,就可以很好的在被代理类NPNormalObject的doSomething方法前添加log或者捕捉异常了。
对于场景类的修改:
- (void)clientInvoke {
// id<DPDynamicProtocol> obj = [[DPNormalObject alloc] init]; // 2
id<DPDynamicProtocol> obj = [[DPDynamicProxy alloc] initWithObject:[[DPNormalObject alloc] init]]; // 3
[obj doSomething];
[obj doOtherThing];
}
只需要將2改为3即可。
https://www.cnblogs.com/ios8/p/ios-daili.html
NSProxy应用例子的更多相关文章
- iOS Class 使用NSProxy和NSObject设计代理类的差异
经常发现在一些需要使用消息转发而创建代理类时, 不同的程序员都有着不同的使用方法, 有些采用继承于NSObject, 而有一些采用继承自NSProxy. 二者都是Foundation框架中的基类, 并 ...
- 使用NSProxy和NSObject设计代理类的差异
经常发现在一些需要使用消息转发而创建代理类时, 不同的程序员都有着不同的使用方法, 有些采用继承于NSObject, 而有一些采用继承自NSProxy. 二者都是Foundation框架中的基类, 并 ...
- SQLServer地址搜索性能优化例子
这是一个很久以前的例子,现在在整理资料时无意发现,就拿出来再改写分享. 1.需求 1.1 基本需求: 根据输入的地址关键字,搜索出完整的地址路径,耗时要控制在几十毫秒内. 1.2 数据库地址表结构和数 ...
- C#+HtmlAgilityPack+XPath带你采集数据(以采集天气数据为例子)
第一次接触HtmlAgilityPack是在5年前,一些意外,让我从技术部门临时调到销售部门,负责建立一些流程和寻找潜在客户,最后在阿里巴巴找到了很多客户信息,非常全面,刚开始是手动复制到Excel, ...
- REGEX例子
作为REGEX的例子,代码9.3显示了一个给定的文件有多少行,具有给定的模式,通过命令行输入(注:有更有效率的方式来实现这个功能,如Unix下的grep命令,在这里只是给出了另一种方式).这个程序像下 ...
- CSharpGL(25)一个用raycast实现体渲染VolumeRender的例子
CSharpGL(25)一个用raycast实现体渲染VolumeRender的例子 本文涉及的VolumeRendering相关的C#代码是从(https://github.com/toolchai ...
- 简单例子了解View的事件分发
什么是事件分发 我们在写自定义ViewGroup或者自定义View的时候经常要处理用户的点击事件,如果我们的View在最底层,他在很多ViewGroup里面,我们如何让我们的点击事件准确传递到View ...
- 简单的例子了解自定义ViewGroup(一)
在Android中,控件可以分为ViewGroup控件与View控件.自定义View控件,我之前的文章已经说过.这次我们主要说一下自定义ViewGroup控件.ViewGroup是作为父控件可以包含多 ...
- kqueue例子
网络服务器通常都使用epoll进行异步IO处理,而开发者通常使用mac,为了方便开发,我把自己的handy库移植到了mac平台上.移植过程中,网上居然没有搜到kqueue的使用例子,让我惊讶不已.为了 ...
随机推荐
- 线程7--GCD的基本使用
子线程执行延时操作,执行完成后返回主线程更新界面 dispatch_queue_t queue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DE ...
- 【转】SQL语句统计每天、每月、每年的数据
原文:https://www.cnblogs.com/Fooo/p/3435687.html SQL语句统计每天.每月.每年的数据 1.每年select year(ordertime) 年,sum(T ...
- zookeeper 典型应用
一.发布/订阅 配置文件的集中管理. 问题:当分布式系统变多后,每个系统保存相应的配置文件,会造成同个文件有多份,修改起来非常麻烦. 解决方法:使用zk的发布/订阅功能,配合Watcher机制,在应用 ...
- Q:链表的倒数第K个元素
问题:如何得到链表中的倒数第k个元素? 一种简单的思路是遍历链表一遍,并统计出链表中节点的数目,然后计算出倒数第k个元素到链表头节点的元素的距离,然后得到对应的结果.但是,我们能否有一种更加简便的 ...
- QT的信号和槽机制简介
信号与槽作为QT的核心机制在QT编程中有着广泛的应用,本文介绍了信号与槽的一些基本概念.元对象工具以及在实际使用过程中应注意的一些问题. QT是一个跨平台的C++ GUI应用构架,它提供了丰富的窗口部 ...
- Android smartimageview网络图片查看器
调用代码: SmartImageView siv = (SmartImageView) findViewById(R.id.siv);siv.setImageUrl(et_path.getText() ...
- web 学习资源
学习 https://skills.bugbank.cn/ https://github.com/JnuSimba/MiscSecNotes 靶场 http://skysec.top/2018/01/ ...
- 重装系统,打开VS进行程序调试运行的时候 Unable to find manifest signing certificate in the certificate store
重装系统,打开VS进行程序调试运行的时候 Unable to find manifest signing certificate in the certificate store. 项目的属性-> ...
- 多张报表导出到一个多sheet页excel
业务需求: 通过勾选不同的报表名称,然后直接执行导出excel.并且这些报表需要统一导入到一个excel的多个sheet页中,并且对某些报表可能需要增加一些类似'已审核'之类的图片(展现时并没有 ...
- RollViewPager图片轮播效果开源框架的使用
RollViewPager是一个自动轮播的Viewpager, 支持无限循环. 触摸时会暂停播放,直到结束触摸一个延迟周期以后继续播放. 看起来就像这样.指示器可以为点可以为数字还可以自定义,位置也可 ...