关于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>公司:先与支 ...
随机推荐
- 你有没有试过“闭上眼”使用:京东、滴滴、QQ、支付宝?
正在看这篇文章的同学,也许是幸运的. 互联网的发展,让我们的生活越来越便利,但这个“我们”,也许并不包括那些残障人士.正常人眼里来说再简单不过的页面操作,对于盲人来说都是不可攀越的高墙.换句话说,越行 ...
- codeforces 677D D. Vanya and Treasure(二维线段树)
题目链接: D. Vanya and Treasure time limit per test 1.5 seconds memory limit per test 256 megabytes inpu ...
- 在phalcon框架下,php接口规范以及接口实例
接口规范实例 前言 由于本人也是第一次写接口,之前对于接口也是一知半解,没有系统的了解过,所以这次也是写的自己的在这几天在APP项目中关于接口的浅层次的认识,如果有不妥或者不当的地方还请指出,再此谢谢 ...
- PHP中变量,常量,超级全局变量小结
//一般来说,变量在函数无法在函数体中无法访问,但是常量可以.//超级全局变量确实可以的,地址栏上的参数/*$GLOBALS //变量注册的信息$_GET //地址栏参数$_POST ...
- Part 97 Performance of a multithreaded program
class Program { static void Main(string[] args) { Stopwatch s = new Stopwatch(); s.Start(); EvenNumb ...
- 网站seo新手快速提升自己的技巧
第一.找自身的问题 大多数从业者都有下面两个严重的问题: 1.过于放大SEO的重要性每个人,都有自大的习惯,地位越NB往往越把自己认知的一切当做真理,其实有可能那只是井口那巴掌大的一片天.在网络营销中 ...
- c# SQL CLR 之一
CLR就是公共运行时,本文就对c#编写SQL StoredProcedures的过程进行简单讲解. [步骤] 2. 3. 7.打开设置 8. 注意删除方式:注意删除Assembly时,一定要先把引用此 ...
- WCF之数据契约
从抽象层面看,WCF能够托管CLR类型(接口和类)并将它们公开为服务,也能够以本地CLR接口和类的方式使用服务.然而,CLR类型却属于.NET的特定技术.由于面向服务的一个核心原则就是在跨越服务边界时 ...
- (转)Linux vmstat命令实战详解
vmstat命令是最常见的Linux/Unix监控工具,可以展现给定时间间隔的服务器的状态值,包括服务器的CPU使用率,内存使用,虚拟内存交换情况,IO读写情况.这个命令是我查看Linux/Unix最 ...
- JavaScript图片轮播器
先贴上html的代码 <div class="ImgDiv"> <div class="Imgs" id="imgScroll&qu ...