iOS中的强代理(strong delegate)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS中的强代理(strong delegate)相关的知识,希望对你有一定的参考价值。
参考技术A 一般来说, ios中的代理都是weak类型的, 这是因为一般代理者都是代理持有者的父对象, 而父对象会持有代理持有者. 因此, 如果代理是强类型, 则会导致循环引用. 虽说代理者不一定得是代理持有者的父对象, 但是这是最常见的使用场合, 用于子对象向父对象传递数据.比如一个UIViewController是一个View的delegate, 在View上的某些操作需要传递给UIViewController, 从而UIViewController做出某些响应.
另一种情况, (父对象)并不需要持有代理持有者, 只是需要在某些操作时做出响应, 而这些响应并不需要(父对象)持有代理持有者, 但是需要代理持有者维持一定的什么周期. 比如一些连接网络的操作. 这时就不会出现循环引用的情况.
到底是使用strong delegate还是weak delegate, 归根结底由调用者(父对象)决定, 调用者是否需要持有代理持有者. 但是话说回来, delegate的weak(strong)属性需要在声明时就指定. 要是遇到有时需要strong delegate有时需要weak delegate时怎么办呢? 这时我们就需要用到另一种回调方式block.
在block中, 当可能引起循环引用时, 不直接持有父对象, 即self对象, 而是使用self对象的弱引用,比如使用 __weak typeof(self) weakSelf = self; 然后在block内部用weakSelf代替self.
在iOS中存在一类strong类型的delegate, 比如CoreAnimation的代理和NSURLSession的代理. 使用强代理是因为动画和网络请求在异步执行, 而异步执行中随时可能会丢失销毁对象, 当执行完成之后再手动销毁对象. 因此要使用strong delegate, 必须当任务完完成时在将delegate=nil来释放delegate.
由于笔者知识有限,如有错误,欢迎讨论指出。
iOS 代理(Delegate)
一、代理的特点
- 准确的说是一种软件设计模式
- iOS当中以
@protocol
形式提现 - 传递方式
一对一
二、代理的基本使用
代理是一种通用的设计模式,在iOS中有特定的语法来实现代理模式,OC语言可以通过@Protocol
实现协议。
1、代理组成部分
- 协议:用来指定代理双方可以做什么,必须做什么。
- 代理:根据协议,完成委托方需要实现的功能(方法)。
- 委托:根据协议,指定代理去完成什么功能。
2、协议(Protocol)的概念
从上图中我们可以看到三方之间的关系,在实际应用中通过协议来规定代理双方的行为,协议中的内容通常情况都是方法列表,当然也可以定义属性.(后面会介绍协议属性)协议是公共的,如果只是单单某个类去使用,我们常做的就是写在某个类中。如果多个类都是使用同一个协议,这里建议大家创建一个Protocol文件,在这个文件中制定协议。遵循的协议可以被继承!
- 协议只能定义公用的一套接口,类似于一个约束代理双方的作用。但不能提供具体的实现方法,实现方法需要代理对象(可以理解为接受协议遵守协议的代理人)去实现。
- 协议可以继承其他协议,也可以继承多个协议,在iOS中对象是不支持多继承的,而协议是可以多继承。
- 协议有两个修饰符@optional和@required,创建一个协议如果没有声明修饰符,默认是@required状态的。这两个修饰符只是约定代理是否强制需要遵守协议,如果@required状态的方法代理没有遵守,Xcode会报一个黄色的警告,@required是需要我们必须实现的。@optional是可以选择实现的.
3、代理原理
我们发现,其实委托方的代理属性本质上就是代理对象自身,设置委托代理就是代理属性指针指向代理对象,相当于代理对象只是在委托方中调用自己的方法,如果方法没有实现就会导致崩溃。从崩溃的信息上来看,就可以看出来是代理方没有实现协议中的方法导致的崩溃。
而协议只是一种语法,是声明委托方中的代理属性可以调用协议中声明的方法,而协议中方法的实现还是由代理方完成,而协议方和委托方都不知道代理方有没有完成,也不需要知道怎么完成。
4、内存管理
我们定义的指针默认都是__strong类型的,而属性本质上也是一个成员变量和set、get方法构成的,strong类型的指针会造成强引用,会造成循环引用。
由于代理方使用强引用指针,引用创建的委托方,并且成为委托方的代理。这就会导致委托方的delegate属性强引用代理方,导致循环引用的问题,最终两个对象都无法正常释放。
三、代理和block对比
- 在有多个消息传递时,用delegate实现更合适,看起来清晰;
- 代理更加面相过程,block则更加面相结果。
- 从设计模式的角度来说,dialing更加面相过程,而block更加面相结果。
- 从性能上来说,block的性能消耗要更略大于delegate,以为block会涉及到栈区向堆区拷贝等操作,时间和空间上的消耗都大于代理。而代理只是定义了一个方法列表,在遵守协议对象的objc_protocol_list中添加一个节点,在运行时向遵守协议的对象发送消息即可。
以上是关于iOS中的强代理(strong delegate)的主要内容,如果未能解决你的问题,请参考以下文章
【iOS】协议(Protocol)和代理(Delegate)
java中的强引用(Strong reference),软引用(SoftReference),弱引用(WeakReference),虚引用(PhantomReference)