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
我思故我在