公司项目里有个定位的功能,决定采用百度地图API来做这个。然后看demo的时候发现一个奇怪的地方:@property (nonatomic, retain) id<BMKMapViewDelegate> delegate;
不太明白为什么这里的delegate要用retain 虽然在注释里也说明了
“/// 地图View的Delegate,此处记得不用的时候需要置nil,否则影响内存的释放
”
我想问下有木有哪位大神这么用过?为什么要这么用呢?什么样的情况下这么用,释放的时候注意哪些才能不内存泄露。拜托了。@tinyfool,@sycx老师有空的话也来看看吧。
上面这个属性是在BMKMapView这个类里面的
不是说delegate就一定要用assign修饰的,这个看情况,有时候基于一些特殊原因delegate也是需要retain。比如官方的NSURLConnection就是一个典型retain了delegate的例子
相信就是这么设计的,总不能理解成百度工程师垃圾不知道delegate用assign吧。一楼楼长说“ 有时候基于一些特殊原因delegate也是需要retain。比如官方的NSURLConnection就是一个典型retain了delegate的例子”我在想如果真是这样,那是什么样的特殊原因呢?@sycx @btxkenshin @terryso @tinyfool 各位大神 你们怎么看?
@terryso 我在文档里看到了这么一句话:“Note: During a download the connection maintains a strong reference to the delegate. It releases that strong reference when the connection finishes loading, fails, or is canceled.”
@morpheus198 嗯,我试验了一下,NSURLConnection的确是会retain它的delegate。不过我想那是因为,NSURLConnection没有一个delegate属性,你必须通过初始化方法把delegate对象传进去,这样NSURLConnection自己就必须retain delegate留来自己用,并且NSURLConnection在请求结束之后,它会自己release它的delegate,这样调用方就不用自己release。 而BMKMapView是有一个delegate属性的,加了retain就会有可能导致retain cycle问题,搞得调用方很麻烦。
@Elden 有一点我想不通,如果是因为异步的问题的话,那开源库ASIHTTPRequest里面异步网络请求的回调函数也是用delegate来调用啊,源码里面的delegate就是用assign的。还是说我对ASIHTTPRequest开源库理解的不够,你觉得呢?@terryso,@tinyfool @sycx
@morpheus198 如果用异步请求,ASIHTTPRequest明确要求在释放之前调用[request clearDelegatesAndCancel]
@Elden ASIHTTPRequest在dealloc函数里调用clearDelegatesAndCancel,这个我知道,问题这跟Delegate用retain或assign没有关系,百度API明确说明了不用的时候要置nil,给的demo也是在willDidDisappear函数里调用setDelegate:nil。那么用不用retain和是不是异步请求是不是没有关系呢?我的疑问在这里,当然也许是我没想通。
@morpheus1984 ASI最早版本当delegate提前释放时候是会crash的,原因就是delegate是assign的,而当时版本的cancel里没有对delegate进行处理,当delegate本身被释放了后ASI还去访问了,导致crash,后来版本专门更新了一个clearDelegateAndCancel的方法
@btxkenshin 感谢回答,clearDelegateAndCancel对于delegate的处理就是set为nil,而delegate本身还是assign的,回到我们最初的疑问,是不是说异步的时候需要考虑delegate提前释放所以要有一个方法将delegate = nil,但是这和delegate是否用retain无关。换句话说假设今天我写了一段代码,为了防止异步导致delegate提前释放而在dealloc里面将delegate = nil 就可以了。这么理解对么?
@morpheus198 你说得没错。 如果你使用ARC的话,把delegate由assign设置为weak的话,你连在dealloc里把delegate设置为nil这步都可以省了。
@btxkenshin ARC好是好,但一开始还要学手动管理内存,否则有时碰到某些坑你根本不知道是为啥形成的。 另外Core API 还是需要手工管理内存。
我始终觉得百度API 那个问题如果说是设计问题,太诡异了。百度工程师的水平能写架构的不可能这么坑。我已经将问题提交了,不知道可有答复。这里有木有认识百度同行的童鞋能否帮忙给问下呢,或者知道的帮忙给解释下。不吝感激啊。@tinyfool
@terryso 这是自然,非ARC用了两年了,切过来以后感觉世界清净了许多。 @morpheus198 对于这个问题我的个人理解其实两种都行,但是什么情况下更需要使用retain自己也没有切身体会,有消息了麻烦分享下啊嘿嘿