当你开始写iOS程式不久,应该开始面对到很多的delegate, 
不管是用别人的library或是自己写library,可能都逃不了delegate。 
为了怕有些人不知道什么是delegate,在这边简单的介绍一下, 
delegate中文叫做委托,通常会用在class内部把一些事件处理"委托"给别人去完成。 
举个例子,XML Parser可能他知道怎么parse xml,但是parse到的东西要怎么处理xml parser可能不知道。 
所以NSXMLParser就提供了一个NSXMLParserDelegate给client去实作, 
当parse到某个element的时候,就callback delegate所定义的message, 
让他client自己去决定怎么去处理这个element。 
好吧,我承认我解释的很模糊,不过我这篇本来就不是要你搞懂什么是delegate, 
而是针对使用或是设计delegate的时候,可能会要注意的事情。

在我们的class中设计delegate的时候,我们通常会有几个注意事项。 
假设我的class叫做MyClass,那我们可能会有定义一个MyClassDelegate这个protocol当作我的delegate protocol。 
而MyClass中我们可能是这样写。 
@protocol MyClassDelegate <NSObject> 
- (void) myClassOnSomeEvent:(MyClass*)myClass; 
@end

@interface MyClass 

    id<MyClassDelegate> _delegate; 

@property (nonatomic, assign) delegate; 
@end 
上面的code我们注意到delegate此property是定义为@property (assign)。 
为什么我们不用retain而要用assign呢? 
原因就是在于iOS的reference counting的环境中,我们必须解决circular count的问题。 
让我们来写写我们平常都怎么用delegate的,下面的code我想大家应该不陌生 
- (void)someAction 

   myClass = [MyClass new]; 
   myClass.delegate = self; 
   .... 

这边很快的就出现circular reference了 
假设上面的code是写在一个myViewController的物件当中, 
之后一旦myViewController的reference count变成1的时候, 
myViewController跟myClass这两个兄弟两只剩下互相retain,那就变成了孤岛,也​​就因此造成了memory leak!!! 

也因为这样,iOS官方文件才会要建议我们所以的delegate都要用assign property。 
也就是所谓"weak reference"的property,他的特色就是虽然会持有对方的reference,但是不会增加retain count。 
如此下来,当myViewController的retain count变成0,则会dealloc。 
同时在dealloc中,也一并把myClass release,则myClass也跟着被release。 
- (void)dealloc 

   [myClass release]; 
   [super dealloc]; 
}

事情就结束了吗? 还没有唷... 
这边还有一个大家常常忘记的重点,那就是上面的dealloc这样写会有潜在危险。 
应该要改成这样 
- (void)dealloc 

   myClass.delegate = nil; 
   [myClass release]; 
   [super dealloc]; 

你可能会很纳闷,myClass不是马上就会被release了吗? 干嘛要先把他的delegate设成nil? 
那是因为我们假设myClass会马上会被dealloc,但是现实状况这个是不一定的, 
有可能里面内部有建个NSURLConnection,或是正在做某件事情而让其他物件也retain myClass。 
如果myClass没有马上dealloc,那他的myClass.delegate不就正指向一个不合法的位置了吗? (此种pointer称作dangling pointer)

解决方法是在MyViewController的dealloc中,在release myClass之前, 
要先把原本指向自己的delegate改设成nil,这样才可以避免crash发生。 
在我之前写的project,很大一部份的crash都是这样造成的,因为这个问题通常不是每次都发生, 
但是发生的时候确很难在重新复制,所以不可不慎啊。

但是很兴奋的是到了iOS5中的Automatic Reference Counting 这个问题可以有所改善。 
在ARC中提出了一个新的weak reference的概念来取代原本的assign, 
weak reference指到的物件若是已经因retain count归零而dealloc了,则此weak reference也自动设成nil。 
而原本​​旧的这种assign的作法,在ARC中叫做__unsafe_unretained,这只是为了相容iOS4以下的版本。

回顾重点: 
如果你是写library给别人用的,记得把你的delegate设成assign property,这样才不会造成circular reference 
当你是要始用别人的library,记得在你自己dealloc的时候,把delegate设成nil,以避免crash的事情发生。

References 
[1]Communicating with Objects

关于IOS中的delegate必须知道的事情的更多相关文章

  1. ios中关于delegate(委托)的使用心得

    ios中关于delegate(委托)的使用心得 分类: iOS开发2012-05-15 10:54 34793人阅读 评论(9) 收藏 举报 iosuiviewtimerinterfaceprinti ...

  2. iOS开发——高级篇——iOS中如何选择delegate、通知、KVO(以及三者的区别)

      在开发IOS应用的时候,我们会经常遇到一个常见的问题:在不过分耦合的前提下,controllers[B]怎么进行通信.在IOS应用不断的出现三种模式来实现这种通信:1委托delegation2通知 ...

  3. iOS中如何选择delegate、通知、KVO(以及三者的区别)

    转载自:http://blog.csdn.net/dqjyong/article/details/7685933 在开发IOS应用的时候,我们会经常遇到一个常见的问题:在不过分耦合的前提下,contr ...

  4. 转iOS中delegate、protocol的关系

    iOS中delegate.protocol的关系 分类: iOS Development2014-02-12 10:47 277人阅读 评论(0) 收藏 举报 delegateiosprocotolc ...

  5. 【学习总结】iOS中NSNotification、delegate、KVO三者之间的区别与联系?

    在开发ios应用的时候,我们会经常遇到一个常见的问题:在不过分耦合的前提下,controllers间怎么进行通信.在IOS应用不断的出现三种模式来实现这种通信: 1.委托delegation: 2.通 ...

  6. iOS 中KVC、KVO、NSNotification、delegate 总结及区别-b

    1.KVC,即是指 NSKeyValueCoding,一个非正式的Protocol,提供一种机制来间接访问对象的属性.而不是通过调用Setter.Getter方法访问.KVO 就是基于 KVC 实现的 ...

  7. iOS中 Proxy和的delegate区别

    在ios中使用proxy代理模式,经常容易和delegate委托模式混淆. 委托模式(delegate),是简单的强大的模式,可让一个对象扮演另外对象的行为.委托对象保持到另外对象的引用,并在适当的时 ...

  8. iOS中NSNotification、delegate、KVO三者之间的区别与联系?

    前面分别讲了delegate.notification和KVO的实现原理,以及实际使用步骤,我们心中不禁有个疑问,他们的功能比较类似,那么在实际的编程中,如何选择这些方式呢? 在网上看到一个博客上详细 ...

  9. iOS中支付宝集成

    iOS中支付宝集成 如今各种的App中都使用了三方支付的功能,现在将我在使用支付宝支付集成过程的心得分享一下,希望对大家都能有所帮助 要集成一个支付宝支付过程的环境,大致需要: 1>公司:先与支 ...

随机推荐

  1. What are definitions of ​Model, Inference and Algorithm and its associations ?

    1.拿初中的二元一次方程来说明: 1.1)说model就好比一元二次方程,它是个方程模型: 1.2)再说inference是求解该方程的某种方法--加减消元法(重在推理): 1.3)最后说algori ...

  2. ionic项目的一些简单操作

    1.首先保证开发环境没问题: 2.下载一个ionic项目:命令ionic start myApp tabs(myApp的项目的名称) 3.在运行项目之前,要先创建平台: ionic platform ...

  3. [转]在WPF中使用WinForm控件方法

    本文转自:http://blog.csdn.net/lianchangshuai/article/details/6415241 下面以在Wpf中添加ZedGraph(用于创建任意数据的二维线型.条型 ...

  4. Winform---文件夹操作

    一.文件夹的操作 private void button1_Click(object sender, EventArgs e) { //文件夹操作 ////新建文件夹 //Directory.Crea ...

  5. PBS常用指令合集

    以下以任务名 job.pbs对应任务ID 12341234为代表,提交者用户名为user. 1.基本指令-最常用 提交作业 qsub job.pbs 查询全部作业 qstat 查询个人作业 qstat ...

  6. 【JS Note】字符串截取

    Js中字符截取常用的三个函数:slice().substring().substr(). slice(): slice(start,[end]) 第一个参数代表开始位置,第二个参数代表结束位置的下一个 ...

  7. JAVA之网页截屏

    先吐槽一下下: 表示接近两个月没有敲代码了,现在看一下代码都感觉有点生了.三天打鱼两天晒网是不行的,再说我本来就有“健忘症”,真的是木有办法啊 ̄へ ̄.我一直信奉一句话:“勤能补拙”,它也是我学习路上的 ...

  8. CentOS7 固定ip

    1. 进入/etc/ network-scripts/ 下ifcfg-eno16777736(文件名可能不一样,单前缀一般是ifcfg-eno) 2. vi打开 编辑  修改bootproro=&qu ...

  9. Objective C中nil/Nil/NULL的区别

    nil:指向oc中对象的空指针 Nil:指向oc中类的空指针 NULL:指向其他类型的空指针,如一个c类型的内存指针 NSNull:在集合对象中,表示空值的对象 若obj为nil:[obj messa ...

  10. 【ASP.NET】DataContract序列化,反序列化对象中包含用接口声明的属性时的处理方法

    为此对象添加KnownType属性(Attribute).类型为用接口声明的属性(Property)的所有可能类型.  示例如下: public interface IKey { [DataMembe ...