在 ARC 下将代表设置为零?

Set delegates to nil under ARC?(在 ARC 下将代表设置为零?)

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

问题描述

我正在使用 ARC 编写 iOS 应用程序并针对 iOS 5+.

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

假设我编写了一个具有委托属性的自定义视图对象.在声明delegate属性时,我将其设为弱引用以避免retain循环,这样当实际的delegate对象(控制器)被销毁时,我的自定义视图也将被销毁,如下:

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 后,我还看到崩溃,其中仅将委托设置为 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 下将代表设置为零?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:在 ARC 下将代表设置为零?