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设计模式 - 代理的更多相关文章

  1. IOS设计模式--代理 (委托)

    原文 http://blog.csdn.net/lovefqing/article/details/8270111 委托(delegate)也叫代理是iOS开发中常用的设计模式.我们借助于protoc ...

  2. IOS设计模式之三:MVC模式

    IOS设计模式之三:MVC模式   模型-视图-控制器 这个模式其实应该叫做MCV,用控制器把model与view隔开才对,也就是model与view互相不知道对方的存在,没有任何瓜葛,他们就像一个团 ...

  3. iOS设计模式 - 中介者

    iOS设计模式 - 中介者 原理图 说明 用一个中介对象来封装一系列的对象交互.中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互. 注:中介者对象本身没有复用价值 ...

  4. iOS书摘之Objective-C编程之道 iOS设计模式解析

    来自<Objective-C编程之道iOS设计模式解析>一书的摘要总结 一.Prototype 原型模式 定义:使用原型实例指定创建对象的种类,并通过复制这个原型创建新的对象.(<设 ...

  5. iOS设计模式 - (1)概述

    近期可自由安排的时间比較多, iOS应用方面, 没什么好点子, 就先放下, 不写了.花点时间学学设计模式. 之后将会写一系列博文, 记录设计模式学习过程. 当然, 由于我自己是搞iOS的, 所以之后设 ...

  6. 9. 星际争霸之php设计模式--代理模式

    题记==============================================================================本php设计模式专辑来源于博客(jymo ...

  7. IOS设计模式之一(MVC模式,单例模式)

    iOS 设计模式-你可能已经听说过这个词,但是你真正理解它意味着什么吗?虽然大多数的开发者可能都会认为设计模式是非常重要的,然而关于设计模式这一主题的文章却不多,并且有时候我们开发者在写代码的时候也不 ...

  8. iOS 设计模式之工厂模式

    iOS 设计模式之工厂模式 分类: 设计模式2014-02-10 18:05 11020人阅读 评论(2) 收藏 举报 ios设计模式 工厂模式我的理解是:他就是为了创建对象的 创建对象的时候,我们一 ...

  9. C++设计模式——代理模式

    前言 青春总是那样,逝去了才开始回味:大学生活也是在不经意间就溜走了,现在上班的时候,偶尔还会怀念大学时,大家在一起玩游戏的时光.大学喜欢玩游戏,但是可悲的校园网,速度能把人逼疯了:还好,后来搞了一个 ...

随机推荐

  1. Eclipse中Maven项目出现红色感叹号问题

    在Eclipse环境下,有时我们会遇到Maven项目出现红色感叹号的情形,而一旦项目出现感叹号,Eclipse便无法帮我们进行自动编译等工作,尽管有时候不会影响运行,但每次只能手动启动Maven重新编 ...

  2. UIKit 框架之Bar、Controller

    UIKit框架中有各种Bar,UITabBar.UINavigationBar.UIToolbar.Bar对应的就有一些Item,tabBarItem.navigationItem.toolbarIt ...

  3. Java - 延迟初始化

    延迟初始化(lazy initialization),也就是在真正被使用的时候才开始初始化的技巧. 不论是静态还是实例,都可以进行延迟初始化. 其本质是初始化开销和访问开销之间的权衡. 毕竟是一种优化 ...

  4. 长期更新系列:C#知识点

    PS:写这个主要是基础差,写这么一个主要是为了自己查漏补缺,不会的搞会了.会了搞的更会.顺便整理知识. 目录 1.C#知识点:值类型和引用类型 2.C#知识点:I/0 3.C#知识点:is和as 4. ...

  5. css3 animation(动画)笔记

    在开始介绍Animation之前我们有必要先来了解一个特殊的东西,那就是"Keyframes",我们把他叫做“关键帧”,玩过flash的朋友可能对这个东西并不会陌生.下面我们就一起 ...

  6. [C语言] 数据结构-预备知识动态内存分配

    动态内存分配 静态内存分配数组 int a[5]={1,2,3,4,5}  动态内存分配数组 int len=5; int *parr=(int *)malloc(sizeof(int) * len) ...

  7. Java并发常见问题

    ConcurrentHashMap源码分析,参考:http://blog.csdn.net/do_smile/article/details/46911727 HashMap源码分析,参考:http: ...

  8. Sql Server 中使用日期遍历

    一个存储过程小案例,内容如下: declare @dt datetime set @dt='2016-01-01' while (@dt<='2016-12-31') begin -- 转换字符 ...

  9. Tomcat启动项目两次

    网上一搜,给出的答案都一样,不外乎:1.删除 Host 标签配置的 appBase="webapps"2.删除 Context 配置 此处这样做:重新添加Tomcat,选择好自己的 ...

  10. async 配合mysql

    async-db.js const mysql = require('mysql') const pool = mysql.createPool({ host : '127.0.0.1', user ...