博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS设计模式 - 代理
阅读量:6894 次
发布时间:2019-06-27

本文共 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/

你可能感兴趣的文章
redis-sentinel 做HA
查看>>
图为先C++笔试20131017
查看>>
模仿墨迹天气-demo
查看>>
mysql基于日志点的复制步骤
查看>>
查看centos中的用户和用户组
查看>>
Elixir ABC 1
查看>>
ZeroSpeech
查看>>
Fiddler 调试手机应用
查看>>
常用的正则表达式
查看>>
Jstl 中<c:if test="${value=='0'}"> 不能做判断??
查看>>
python matplotlib及sklearn安装
查看>>
困惑2017?
查看>>
KOTree
查看>>
BlockAlertsAnd-ActionSheets
查看>>
开源 java CMS - FreeCMS2.5 标签formTable自定义表单
查看>>
FreeCMS视频教程 将FreeCMS导入myeclipse
查看>>
Android 8.0 SystemUI(一):图文并茂的介绍 :D
查看>>
1wifi 简介(框架)
查看>>
internet && intranet
查看>>
go get报错 error: RPC failed; result=56, HTTP code =
查看>>