iOS开发学习笔记:基础知识之代理模式之老王的故事

2019-02-252309

image

设计模式在各个领域都得到广泛应用,是在特定场景下对特定问题的解决方案,这些解决方案都是经过反复的论证测试而总结出来的。

在接触到项目时,很多地方都会使用到设计模式。而这段时间的项目需要用到代理较多,而本人对代理设计模式还比较模糊,故本文会从自身学习过程来说,主要解析代理的一些知识。

首先是一些概念

在项目中需要进行消息传递,接触得比较多的是传值、传事件:

  • 传值:常用于A类要把自己的一个数据或者对象传到B类,让B类去处理。
  • 传事件:A类发生了什么事,要把这件事告诉委托的对象,由他去进行反应。

而在iOS中有很多消息传递方式,简单列举有:

  • 通知:看名称比较好理解,是一种一对多的消息传递方式,是由通知中心对消息进行接收和广播。
  • block:可以将回调处理代码直接写在block代码块中。
  • KVO:Category—NSKeyValueObserving,通过属性监听的方式来检测某个值的变化,当值发生变化时调用KVO的回调方法。
  • target action:通过将对象传递到另一个类中,在其中将该对象当做target的方式来调用对象方法,从内存角度来说与代理类似。
  • 代理:是一种通用的设计模式,iOS中对代理支持的很好,由代理对象、委托者、协议三部分组成。

其实在学习到代理之前,用的 target action 比较多,它只有一个参数,并且无返回值的,场景适用于单个事件,主要用于系统的类中。而代理可以有多个参数,可以有 BOOL 类型的返回值,来确定是否可以执行下一个方法。能处理多个事件,经常用于自己设计的程序中。

代理是一种通用的设计模式,有特定的语法来实现,主要由三部分组成:

  • 协议:规定代理双方的行为
  • 委托:委托方,指定代理去完成什么
  • 代理:接受委托方 or 委托对象,完成委托方需要实现的事

协议是什么:

顾名思义就是要遵循的规则。在协议中定义了一些方法,如果代理想要实现这个协议中的一系列方法,就必须遵守这个协议。这也说明这种模式是单向的,消息的发送方(委托方) 需要知道接收方(代理方)是谁,即只需要知道它的代理方是否遵守了协议反过来是不需要的。利用协议可以进行对象之间的相互通信,还可将数据与业务逻辑解耦。

协议有两种模式:

  • 委托模式:信息通过协议中的方法参数从委托方流向代理方,或者事件发生时,委托者通知代理者 ,简单表述为:委托方传递信息或者事件到代理方。
  • 数据源模式:数据源模式的信息流向与委托模式正好相反,委托方需要从代理方拉取数据。 简单表述为:代理方传递信息到委托方。

从简单的例子出发

先设定情景:我有个朋友阿白,他家同一栋楼的邻居是个身材很好的漂亮妹子小蓝,最近天气那么冷,还是能看到小蓝经常在屋子里跑跑跳跳。朋友纳闷啊,是不是她家里的空调坏了,要运动来发保持身体热量啊。阿白天生热心肠,想去帮小蓝看看空调坏没坏。但是他害羞啊,只能找人帮他去看看,他想到了在网上发布告示招人,便发帖,上面写着“阿白招跑腿之行动指南——从我家去到妹子小蓝家”,能做到这件事的都可以来。老王手速最快,态度最积极,所以我就拿老王跑腿的事来做范例。

这个例子是基于 MVC 设计模式的。

这里,

阿白就是委托( HomeOfMyFriend 文件),

老王就是代理( ViewController 文件),

帖子内容就是协议,里面写的内容就是老王走去妹子家这件事。

先写协议和委托

HomeOfMyFriend.h 中:

  • 阿白首先要写协议,协议要写协议名和内容吧(也就是方法),待会儿老王要遵循这个协议,执行这个方法的。So,用当前页面文件名+Delegate作为协议名,并列出方法。

  • 有了这个协议以后,那么就需要用一个属性来存放委托对象了。这个属性需定义成 weak ,而不是用 strong ,如果使用 strong ,委托方持有委托对象,委托对象也会持有委托方,两个对象之间都是强应用,形成你中有我,我中有你的关系,就会形成循环引用(retain circle) 造成这两个对象无法销毁。

HomeOfMyFriend.m 中:

  • 然后老王来到阿白家,阿白给了指令以后老王才会出发,执行从阿白家到妹子家这件事。

HomeOfMyFriend.m 中,我会以点击事件 @selector(WangGo) 来代表阿白指派老王出发。

再写代理

ViewController.m

  • 老王要遵守协议,所以在 ViewController.m 中,要继承协议。

  • 老王作为行动者、代理方,当然还要对协议中的方法进行实现

  • 然而我们要在 ViewController.mHomeOfMyFriend 的实例中注册 delegate 才行。

注册 delegate 是什么意思呢?故事内描述出来,就是:注册 delegate 后,老王才得以表明身份,在小蓝门前“咚咚咚”敲门说:“小蓝呀,我是受你邻居阿白委托来看你的,你不要害怕,让我进去吧~”。

故事就在我朋友阿白发出指令“老王Go!”(点击按钮,触发 WangGo 方法),老王心急火燎马不停蹄从阿白家去到小蓝家(从 HoneOfMyFriend 跳转到 XiaoLanHouseController )的唯美画面中,结束啦!


本渣故事、小栗子可能是一个再普通不过的实现,其实也是我学习路上曾经花了挺多时间去理解的一个地方,本意是为了加深对代理模式某一功能、某一方面的理解,若有幸能给各位看官大佬们带来一点帮助或者是一丝丝笑意,或者能得到一些指导指正,对本菜鸟来说就是莫大的乐事了!

分享
点赞2
打赏
上一篇:iOS 中 Widget 的实现 | 实战系列
下一篇:Objective-C基础学习及知识点总结