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. tomcat启动(五)Catalina分析-service.init

    上篇写到StandardService.init() 这个方法做什么呢?一起来看看. 这个类也是实现了Lifecycle 如图.这个图中i表示Interface接口.如Lifecycle,Contai ...

  2. Linux下串口編程遇到的接收数据错误及原因(0x0d,0x11接收错误)

    摘要:Linux下串口编程遇到的接收数据错误及原因 来源:https://dotblogs.com.tw/k/2012/07/24/73572 近日在调试串口的时候发现,另一设备向我ARM板的串口发送 ...

  3. Go 提高性能的特性

    1.值的高效处理和存储,允许创建紧凑的数据结构,避免不必要的填充字节.紧凑的数据结构能更好地利用缓存.更好的缓存利用率可带来更好的性能. 2.函数的调用有开销,减少函数调用开销的解决方案是内联.简单的 ...

  4. WPF在XAML的资源中定义空字符串String.Empty

    代码如下: <!--1. 首先引用System的命名空间--> <Window x:Class="DriverEasyWPF.Views.DialogWindow" ...

  5. MJRefresh源码框架分析

    MJRefresh是一款非常优秀的刷新控件.代码简洁,优雅.今天有时间对源代码阅读了一下.对MJRefresh的宏观设计非常赞叹.所谓大道至简就是这样吧.   MJRefresh所采用的主要设计模式非 ...

  6. 前端神器之Sublime Text2/3简单明了使用总结

    为什么叫神器呢? 我总结如下: 第一:也是最重要的,它占内存很小(就如同notepad++那般迅速打开,所以那款其实也不错~).一般IDE比如WebStorm(它也是一款神器来着),Aptana(也比 ...

  7. [BZOJ 5074]小B的数字

    Description 题库链接 给你一个长度为 \(n\) 的序列 \(a_1,a_2,\cdots,a_n\) ,让你生成另一个序列 \(b_1,b_2,\cdots,b_n\) ,使得 \(\f ...

  8. UIKit 框架之UICollectionView

    1.自定义UICollectionViewCell 在myCollectionViewCell.h中声明两个属性 // // myCollectionViewCell.h // UICollectio ...

  9. C# 谁改了我的代码

    本文告诉大家一个特殊的做法,可以修改一个字符串常量 我们来写一个简单的程序,把一个常量字符串输出 private const string str = "lindexi"; sta ...

  10. weixin.com域名易主 传交易价格仅次360.com

    据业内人士透露,weixin.com双拼域名今日易主,交易价格在几千万级别,有传闻其交易价格仅次于360.com. 从whois信息查看可知,weixin.com域名信息今日发生变更,目前域名的持有者 ...