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++设计模式——代理模式
前言 青春总是那样,逝去了才开始回味:大学生活也是在不经意间就溜走了,现在上班的时候,偶尔还会怀念大学时,大家在一起玩游戏的时光.大学喜欢玩游戏,但是可悲的校园网,速度能把人逼疯了:还好,后来搞了一个 ...
随机推荐
- golang笔记(1)-数据库查询结果映射至结构体
通用的映射模式 query:="select id,name from user where id=?" //单个结构体ret:=&Activity{} DbClient( ...
- 解决nginx访问问题connect() to 127.0.0.1:8080 failed (13: Permission denied) while connecting to upstream,
问题:搭建好项目之后,用nginx进行代理,进行日常配置之后,发现前端正常访问,但是后端访问出现错误,报502错误,查找nginx日志,发现connect() to 127.0.0.1:8080 fa ...
- GreenPlum:基于PostgreSQL的分布式关系型数据库
GreenPlum是一个底层是多台PostgreSQL分表分库的分布式数据库,它有如下特点 支持标准SQL,几乎所有PostgreSQL支持的SQL,greenplum都支持 支持ACID.分布式事务 ...
- json-lib使用——JSONObject与JSONArray
ps:看这篇博客之前首先要引入工具包json-lib-2.2.2-jdk15.jar 资源链接:百度云:链接:https://pan.baidu.com/s/1o9k7PSu 密码:00lj 一.从O ...
- rails中params[:id]与params["id"]分析
写这个帖子的缘由是因为在页面参数传到rails的controller时用params[:]和params[""]都可以取到值: [1] pry(#<BooksControll ...
- 【持续更新】一个简洁、易用的美赛LaTeX模板: easyMCM
目录 1 当前美赛模板通行情况的概述 2 easymcm宏包说明 2.1 与mcmthesis的关系之说明 2.2 easymcm宏包的简介 2.3 美赛模板下载地址 3 常见问题的解决方案 若您无意 ...
- 自动化部署MySQL 5.6 步骤 制作到ftp共享,永远使用
首先需要搭建ftpserver yum install vsftpd service vsftpd start 这样ftp服务就起来了,这里只是简单的使用,所以没有使用配置文件.这样我们只要将需要的文 ...
- Ionic APP 热更新
开门见山,本文主题:cordova-hot-code-push 作用:cordova热更新插件,提供了在应用程序中对基于Web的内容进行自动更新的功能. GitHub地址:https://github ...
- .NET创建WebService服务简单的例子
Web service是一个基于可编程的web的应用程序,用于开发分布式的互操作的应用程序,也是一种web服务 WebService的特性有以下几点: 1.使用XML(标准通用标记语言)来作为数据交互 ...
- Python__random库基本介绍
random库是使用随机数的Python标准库 从概率论角度来说,随机数是随机产生的数据(比如抛硬币),但时计算机是不可能产生随机值,真正的随机数也是在特定条件下产生的确定值,只不过这些条件我们没有理 ...