首页 > 学院 > 开发设计 > 正文

iOS的动态代理模式的实现

2019-11-14 20:38:25
字体:
来源:转载
供稿:网友
动态代理模式的应用很多,特别是在不能修改被代理类的前提下,要对执行某些方法时需要打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即可。


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表