本文共 3132 字,大约阅读时间需要 10 分钟。
iOS设计模式 - 代理
原理图
说明
1. 代理模式大家都用过,但用抽象基类NSProxy实现代理估计鲜有人用
2. 本人用NSProxy实现了代理模式,对于理解消息转发机制有点帮助
源码
//// AbstractProxy.h// AppProxy//// Created by YouXianMing on 15/8/4.// Copyright (c) 2015年 YouXianMing. All rights reserved.//#import@interface AbstractProxy : NSProxy/** * 被代理对象 */@property (nonatomic, weak) id customer;/** * 代理客户 * * @param customer 实现了某种协议的客户 * * @return 代理对象 */- (instancetype)initWithCustomer:(id)customer;@end
//// AbstractProxy.m// AppProxy//// Created by YouXianMing on 15/8/4.// Copyright (c) 2015年 YouXianMing. All rights reserved.//#import#import "AbstractProxy.h"#import "AbstractExcute.h"@implementation AbstractProxy- (instancetype)initWithCustomer:(id)customer { self.customer = customer; return self;}#pragma mark - NSProxy- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector { if ([self.customer respondsToSelector:aSelector]) { return [self.customer methodSignatureForSelector:aSelector]; } else { AbstractExcute *excute = [AbstractExcute shareInstance]; return [excute methodSignatureForSelector:NSSelectorFromString(@"nullExcute:")]; }}- (void)forwardInvocation:(NSInvocation *)invocation { SEL selector = [invocation selector]; if ([self.customer respondsToSelector:selector]) { [invocation setTarget:self.customer]; [invocation invoke]; } else { NSString *selectorString = NSStringFromSelector(invocation.selector); invocation.selector = NSSelectorFromString(@"nullExcute:"); AbstractExcute *excute = [AbstractExcute shareInstance]; [invocation setTarget:excute]; const char *className = class_getName([self class]); NSArray *classNameArray = nil; if (self.customer) { classNameArray = @[[NSString stringWithUTF8String:className], selectorString, @""]; } else { classNameArray = @[[NSString stringWithUTF8String:className], selectorString]; } [invocation setArgument:&classNameArray atIndex:2]; [invocation invoke]; }}@end
//// AbstractExcute.h// AppProxy//// Created by YouXianMing on 15/8/4.// Copyright (c) 2015年 YouXianMing. All rights reserved.//#import@interface AbstractExcute : NSObject+ (instancetype)shareInstance;@end
//// AbstractExcute.m// AppProxy//// Created by YouXianMing on 15/8/4.// Copyright (c) 2015年 YouXianMing. All rights reserved.//#import "AbstractExcute.h"@implementation AbstractExcute+ (instancetype)shareInstance { static AbstractExcute *sharedAbstractExcute = nil; static dispatch_once_t predicate; dispatch_once(&predicate, ^{ sharedAbstractExcute = [[self alloc] init]; }); return sharedAbstractExcute;}- (void)nullExcute:(NSArray *)className { if (className.count == 3) { NSLog(@"%@ 设置了代理,但该代理没有实现 %@ 方法", className[0], className[1]); } else { NSLog(@"%@ 没有设置代理,方法 %@ 没有执行", className[0], className[1]); } }@end
细节
NSProxy子类实现的关键所在
转载地址:http://icudl.baihongyu.com/