在ARC下将代表设置为nil? [英] Set delegates to nil under ARC?

查看:91
本文介绍了在ARC下将代表设置为nil?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用ARC编写iOS应用,并定位到iOS 5 +.

I'm writing iOS apps using ARC and targeting iOS 5+.

假设我编写了一个具有委托属性的自定义视图对象.在声明委托属性时,我将其作为弱引用以避免保留周期,以便当实际的委托对象(控制器)被销毁时,我的自定义视图也将被销毁,如下所示:

Suppose I write a custom view object that has a delegate property. In declaring the delegate property, I make it a weak reference to avoid a retain cycle, so that when the actual delegate object (the controller) is destroyed, my custom view will also be destroyed, as follows:

@interface MyCustomView : UIView

@property (nonatomic, weak) id<MyCustomViewDelegate> delegate;

@end

一切都很好.

好吧,所以现在我在编写控制器对象,它引用了两个视图对象:我的自定义视图和Apple提供的UIKit视图,这两个都声明了委托属性,而控制器是这两个的委托意见.也许看起来像这样:

Ok, so now I'm writing the controller object, and it has references to two view objects: my custom view and an Apple-supplied UIKit view, both of which declare delegate properties, and the controller is the delegate for both views. Maybe it looks something like this:

@interface MyViewController : UIViewController <MyCustomViewDelegate, UITableViewDataSource, UITableViewDelegate>

@property (nonatomic, strong) MyCustomView *customView;
@property (nonatomic, strong) UITableView *tableView;

@end

@implementation MyViewController

- (void)viewDidLoad
{
    self.customView.delegate = self;
    self.tableView.dataSource = self;
    self.tableView.delegate = self;
}

@end

我的问题是:我是否需要重写dealloc来将一个或两个委托都设置为nil?

My question is this: Do I need to override dealloc to set either or both delegates to nil?

我的意思是,据我所知,实际上,UIKit视图的委托属性(在本例中为tableView)并不是声明为弱引用,而是声明为__unsafe_unretained引用,以实现与...的向后兼容性.非ARC版本的iOS.所以也许我需要写

I mean, as I understand it, the delegate property of the UIKit view (in this case, tableView) isn't actually declared to be a weak reference, but rather an __unsafe_unretained reference, for backwards compatibility with non-ARC version of iOS. So maybe I need to write

- (void)dealloc
{
    _tableView.dataSource = nil;
    _tableView.delegate = nil;
}

现在,如果我必须重写dealloc,我仍然不必设置_customView.delegate = nil,对吗?由于(我)宣布该值为弱引用,因此在MyViewController销毁后应将其自动设置为nil.

Now, if I do have to override dealloc, I still don't have to set _customView.delegate = nil, right? Because that was declared (by me) to be a weak reference, so it should be set to nil automatically upon the destruction of MyViewController.

但是,另一方面,我的目标不是非ARC版本的iOS,也不是我打算的目标.所以也许我根本不需要重写dealloc?

But on the other hand, I'm not targeting non-ARC versions of iOS, nor do I intend to. So maybe I don't need to override dealloc at all?

推荐答案

将非弱委托设置为nil通常是一个好主意,除非您知道不必这样做.对于UITableViewUIScrollView,我在iOS以前的版本上经历了以下步骤的崩溃(可能会在启用僵尸的情况下运行):

Setting non-weak delegates to nil is generally a good idea unless you know you don't have to. For UITableView and UIScrollView, I've experienced crashes on previous iOS versions with the following steps (it may help to run with zombies enabled):

  1. 滚动非常快.
  2. 按[完成]或返回按钮或任何其他方法可关闭VC.

这似乎是由于滚动动画保留了对视图的引用而导致的,因此视图的寿命超过了VC.发送滚动事件时崩溃.

This appears to happen because the scrolling animation is retaining a reference to the view, so the view outlives the VC. It crashes when sending the scroll event.

在加载请求时,关闭包含UIWebView的VC后,我也看到了崩溃,在该VC中,仅将委托设置为nil是不够的(我认为解决方法是调用[webView loadRequest:nil]).

I've also seen crashes after dismissing a VC containing a UIWebView while a request is being loaded, where simply setting the delegate to nil was not sufficient (I think the workaround was to call [webView loadRequest:nil]).

这篇关于在ARC下将代表设置为nil?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆