【发布时间】:2013-02-22 12:11:45
【问题描述】:
我正在使用 ARC 编写 iOS 应用程序并针对 iOS 5+。
假设我编写了一个具有委托属性的自定义视图对象。在声明delegate属性时,我将其设为弱引用以避免retain循环,这样当实际的delegate对象(控制器)被销毁时,我的自定义视图也将被销毁,如下:
@interface MyCustomView : UIView
@property (nonatomic, weak) id<MyCustomViewDelegate> delegate;
@end
一切都好。
好的,现在我正在编写控制器对象,它引用了两个视图对象:我的自定义视图和 Apple 提供的 UIKit 视图,它们都声明了委托属性,控制器是两者的委托意见。也许它看起来像这样:
@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?
我的意思是,据我了解,UIKit 视图的委托属性(在本例中为 tableView)实际上并未声明为弱引用,而是声明为 __unsafe_unretained 引用,以便向后兼容非 ARC 版本的 iOS。所以也许我需要写
- (void)dealloc
{
_tableView.dataSource = nil;
_tableView.delegate = nil;
}
现在,如果我必须重写 dealloc,我仍然不必设置 _customView.delegate = nil,对吗?因为这被(我)声明为弱引用,所以它应该在 MyViewController 销毁时自动设置为 nil。
但另一方面,我不针对非 ARC 版本的 iOS,也不打算这样做。所以也许我根本不需要覆盖 dealloc?
【问题讨论】:
-
您可能没有意识到这一点,但目前的建议是包含在视图层次结构中 的 IBOutlets 应该是弱的。换句话说,如果 tableView 包含在视图中,则视图由强引用持有,而 tableView 不需要。这使您的案例有点人为,尽管对于该案例(还有其他更真实的实例)仍然是一个合理的问题。
-
@StevenFisher 谢谢,史蒂文。我知道这一点,但在我的示例中,我没有将视图属性声明为 IBOutlets;也许我是以编程方式而不是通过 IB 生成它们。
-
@StevenFisher 我想我最好奇的是 '__weak' 和 '__unsafe_unretained' 属性声明之间的区别,以及针对 iOS 的后 ARC 版本时我对这些不同声明的责任是什么.
-
哎呀!你是对的。道歉。我已经习惯了看到 IBOutlet 我没有注意到它什么时候不存在。这是个好问题。 :)
标签: ios delegates automatic-ref-counting