当你开始写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. nginx 反向代理设置

    假设对本机80端口的访问为一台服务器,对本机8000端口的访问为另一台服务器,下面这样写一个nginx的反向代理配置,就可以实现所有请求都转移 server {listen 0.0.0.0:80;se ...

  2. Umbraco(3) - CSS & Javascript(翻译文档)

    原文地址:http://www.ncloud.hk/%E6%8A%80%E6%9C%AF%E5%88%86%E4%BA%AB/umbraco3css-javascript/ CSS & Jav ...

  3. DevExpress使用之ChartControl控件绘制图表(多坐标折线图、柱状图、饼状图)

    最近因为公司项目需要用到WinForm的DecExpress控件,在这里把一些使用方法总结一下. DevExpress中有一个专门用来绘制图表的插件ChartControl,可以绘制折线图.饼状图.柱 ...

  4. 设置input(radio,checkbox)和lable对齐的问题

    在做页面的时候几次遇到label和前面的小图标无法对齐的情况,后来发现解决方法不过是 label { display:inline-block; vertical-align:top; line-he ...

  5. 出现,视图必须派生自 WebViewPage 或 WebViewPage错误解决方法

    遇到这种问题是因为我新建了Areas,在Areas里面建Controllers,Models,Views.所以在View文件夹下面湿没有Web.config文件的. 解决方法:(复制views中的we ...

  6. git and github学习笔记

    1.git的状态分为working status,stage status和commit status.git diff查看的是working status和 stage status之间的不同,gi ...

  7. 【转载】存储过程实现FTP上传下载

    CREATE OR REPLACE PACKAGE ftp AS -- ---------------------------------------------------------------- ...

  8. 《iOS开发指南》要改iOS8版本了,听听您的意见?

    <iOS开发指南>要改iOS8版本了,听听您的意见?参加问卷同学均可获得智捷课堂50元代金卡一张,同时抽取一名同学赠送即将出版的基于iOS8的<iOS开发指南>一本,欢迎大家填 ...

  9. VC中调用COM组件的方法(转载)

    原文参考:http://hi.baidu.com/mingyueye/item/53ebecd44da76917d80e4449 总结一下在VC中调用COM组件的方法 准备及条件: COM服务器为进程 ...

  10. (转)在 Windows 上安装Rabbit MQ 指南

    rabbitMQ是一个在AMQP协议标准基础上完整的,可服用的企业消息系统.他遵循Mozilla Public License开源协议.采用 Erlang 实现的工业级的消息队列(MQ)服务器. Ra ...