iOS设计模式 - 代理
iOS设计模式 - 代理

原理图

说明
1. 代理模式大家都用过,但用抽象基类NSProxy实现代理估计鲜有人用
2. 本人用NSProxy实现了代理模式,对于理解消息转发机制有点帮助
源码
https://github.com/YouXianMing/iOS-Design-Patterns
//
// AbstractProxy.h
// AppProxy
//
// Created by YouXianMing on 15/8/4.
// Copyright (c) 2015年 YouXianMing. All rights reserved.
// #import <Foundation/Foundation.h> @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 <objc/runtime.h>
#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:];
[invocation invoke];
}
} @end
//
// AbstractExcute.h
// AppProxy
//
// Created by YouXianMing on 15/8/4.
// Copyright (c) 2015年 YouXianMing. All rights reserved.
// #import <Foundation/Foundation.h> @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 == ) { NSLog(@"%@ 设置了代理,但该代理没有实现 %@ 方法", className[], className[]); } else { NSLog(@"%@ 没有设置代理,方法 %@ 没有执行", className[], className[]);
} } @end
细节
NSProxy子类实现的关键所在

iOS设计模式 - 代理的更多相关文章
- IOS设计模式--代理 (委托)
原文 http://blog.csdn.net/lovefqing/article/details/8270111 委托(delegate)也叫代理是iOS开发中常用的设计模式.我们借助于protoc ...
- IOS设计模式之三:MVC模式
IOS设计模式之三:MVC模式 模型-视图-控制器 这个模式其实应该叫做MCV,用控制器把model与view隔开才对,也就是model与view互相不知道对方的存在,没有任何瓜葛,他们就像一个团 ...
- iOS设计模式 - 中介者
iOS设计模式 - 中介者 原理图 说明 用一个中介对象来封装一系列的对象交互.中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互. 注:中介者对象本身没有复用价值 ...
- iOS书摘之Objective-C编程之道 iOS设计模式解析
来自<Objective-C编程之道iOS设计模式解析>一书的摘要总结 一.Prototype 原型模式 定义:使用原型实例指定创建对象的种类,并通过复制这个原型创建新的对象.(<设 ...
- iOS设计模式 - (1)概述
近期可自由安排的时间比較多, iOS应用方面, 没什么好点子, 就先放下, 不写了.花点时间学学设计模式. 之后将会写一系列博文, 记录设计模式学习过程. 当然, 由于我自己是搞iOS的, 所以之后设 ...
- 9. 星际争霸之php设计模式--代理模式
题记==============================================================================本php设计模式专辑来源于博客(jymo ...
- IOS设计模式之一(MVC模式,单例模式)
iOS 设计模式-你可能已经听说过这个词,但是你真正理解它意味着什么吗?虽然大多数的开发者可能都会认为设计模式是非常重要的,然而关于设计模式这一主题的文章却不多,并且有时候我们开发者在写代码的时候也不 ...
- iOS 设计模式之工厂模式
iOS 设计模式之工厂模式 分类: 设计模式2014-02-10 18:05 11020人阅读 评论(2) 收藏 举报 ios设计模式 工厂模式我的理解是:他就是为了创建对象的 创建对象的时候,我们一 ...
- C++设计模式——代理模式
前言 青春总是那样,逝去了才开始回味:大学生活也是在不经意间就溜走了,现在上班的时候,偶尔还会怀念大学时,大家在一起玩游戏的时光.大学喜欢玩游戏,但是可悲的校园网,速度能把人逼疯了:还好,后来搞了一个 ...
随机推荐
- Ubuntu系统下OpenDaylight源码编译安装
操作系统:Linux x64 / Ubuntu 14.04 研究领域:软件定义网络SDN (Software-defined Networking) 开发组件:OpenDaylight 声明:转载请注 ...
- 使用Visual Studio Code搭建PHP调试环境
1.需要安装的软件 Visual Studio Code. WAMP(包括Apache.MySQL.PHP.以及最关键的XDebug) 2.下载软件 Visual Studio Code,光看名字就知 ...
- 进击Node.js基础(二)
一.一个牛逼闪闪的知识点Promise npm install bluebird 二.Promise实例 ball.html <!doctype> <!DOCTYPE html> ...
- ruby执行周期性任务
1.前言 无论是用ruby做系统管理,还是用rails做web开发,都可能遇到周期性任务,它们按照一定时间周期(1小时,2天......)持续地触发.在ruby中,我认为一次性任务使用sid ...
- 功能------常用快捷键(在win10下)
功能------win10 常用快捷键 在进行学习,记录,编写代码时,需要用到一些功能,用鼠标浪费时间,可以使用快捷键来快速的处理.方便操作. 以下内容分为两类.快捷键以及触控板类(不能享用鼠标) 快 ...
- C语言——<计算>_较大两个数相乘
例题:9876543210*1234567890 的乘积 分析:正常的数据结构已经无法满足这么大的数相乘的结果.只能使用数组来进行操作. 1.两个数都用字符数组来接收. 2.接收后,因为每一位要乘以另 ...
- hadoop学习笔记(三):hadoop文件结构
hadoop完整安装目录结构: 比较重要的包有以下4个: src hadoop源码包.最核心的代码所在目录为core.hdfs和mapred,他们分别实现了hadoop最重要的3个模块:基础公共库.H ...
- 常用js-API
jquery.base64.js //下面是64个基本的编码 var base64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklm ...
- LeetCode刷题第二天
2.给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们 ...
- Java Swing实战(二)下拉菜单组件JComboBox及其事件监听
接下来给"数据源配置"面板添加下拉框. /** * @author: lishuai * @date: 2018/11/26 13:51 */ public class Weimi ...