关于IOS中的delegate必须知道的事情
当你开始写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必须知道的事情的更多相关文章
- ios中关于delegate(委托)的使用心得
ios中关于delegate(委托)的使用心得 分类: iOS开发2012-05-15 10:54 34793人阅读 评论(9) 收藏 举报 iosuiviewtimerinterfaceprinti ...
- iOS开发——高级篇——iOS中如何选择delegate、通知、KVO(以及三者的区别)
在开发IOS应用的时候,我们会经常遇到一个常见的问题:在不过分耦合的前提下,controllers[B]怎么进行通信.在IOS应用不断的出现三种模式来实现这种通信:1委托delegation2通知 ...
- iOS中如何选择delegate、通知、KVO(以及三者的区别)
转载自:http://blog.csdn.net/dqjyong/article/details/7685933 在开发IOS应用的时候,我们会经常遇到一个常见的问题:在不过分耦合的前提下,contr ...
- 转iOS中delegate、protocol的关系
iOS中delegate.protocol的关系 分类: iOS Development2014-02-12 10:47 277人阅读 评论(0) 收藏 举报 delegateiosprocotolc ...
- 【学习总结】iOS中NSNotification、delegate、KVO三者之间的区别与联系?
在开发ios应用的时候,我们会经常遇到一个常见的问题:在不过分耦合的前提下,controllers间怎么进行通信.在IOS应用不断的出现三种模式来实现这种通信: 1.委托delegation: 2.通 ...
- iOS 中KVC、KVO、NSNotification、delegate 总结及区别-b
1.KVC,即是指 NSKeyValueCoding,一个非正式的Protocol,提供一种机制来间接访问对象的属性.而不是通过调用Setter.Getter方法访问.KVO 就是基于 KVC 实现的 ...
- iOS中 Proxy和的delegate区别
在ios中使用proxy代理模式,经常容易和delegate委托模式混淆. 委托模式(delegate),是简单的强大的模式,可让一个对象扮演另外对象的行为.委托对象保持到另外对象的引用,并在适当的时 ...
- iOS中NSNotification、delegate、KVO三者之间的区别与联系?
前面分别讲了delegate.notification和KVO的实现原理,以及实际使用步骤,我们心中不禁有个疑问,他们的功能比较类似,那么在实际的编程中,如何选择这些方式呢? 在网上看到一个博客上详细 ...
- iOS中支付宝集成
iOS中支付宝集成 如今各种的App中都使用了三方支付的功能,现在将我在使用支付宝支付集成过程的心得分享一下,希望对大家都能有所帮助 要集成一个支付宝支付过程的环境,大致需要: 1>公司:先与支 ...
随机推荐
- PBS常用指令合集
以下以任务名 job.pbs对应任务ID 12341234为代表,提交者用户名为user. 1.基本指令-最常用 提交作业 qsub job.pbs 查询全部作业 qstat 查询个人作业 qstat ...
- 【转】ASP.NET 高效分页存储过程
代码 Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-- ...
- (转)浅谈.NET下的多线程和并行计算(一)前言
转载——原文地址:http://www.cnblogs.com/lovecindywang/archive/2009/12/25/1632014.html 作为一个ASP.NET开发人员,在之前的开发 ...
- 人情世故&潜规则
大凡成功的牛人,无一例外都明白这一点.他们读懂了社会的本质和人际交往的潜规则,知道对方需要什么,知道对方脑子里在想什么.你几乎看不见他奔波劳碌,但是在不动声色中,他就已经实现人生目标.他们成功的密码是 ...
- Part 1 some difference from asp.net to asp.net mvc4
Part 1 some difference from asp.net to asp.net mvc4 In MVC URL's are mapped to controller Action Met ...
- Cocos2d-JS特效
Cocos2d-JS提供了很多特效,这些特效事实上属于间隔动作,特效类cc.GridAction类,也称为网格动作,它的类图如下图所示. 网格动作类图 网格动作cc.GridAction它有两个主要的 ...
- HTML+CSS学习笔记 (13) - CSS代码缩写,占用更少的带宽
标签:HTML+CSS 盒模型代码简写 还记得在讲盒模型时外边距(margin).内边距(padding)和边框(border)设置上下左右四个方向的边距是按照顺时针方向设置的:上右下左.具体应用在m ...
- hdu 1002大数(Java)
A + B Problem II Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- Javascript Event
事件原理 JS的事件原理,先看一段HTML. <html> <head> <title>Example</title> </head> &l ...
- 一个小makefile程序
刚刚开始学习linux下的程序,总需要自己写一些小型的makefile文件,这里给出一个makefile的例子,方便以后借鉴. 程序包含了main.c(需要头文件input.h 和 display.h ...