Swift UITableView委托和dataSource声明和保留周期

时间:2014-06-28 16:11:34

标签: ios swift

据我所知,要在swift中使用委托模式,我必须声明一个这样的属性:

weak var delegate: TheDelegateProtocol!

这样的协议:

@class_protocol protocol TheDelegateProtocol {

}

避免保留周期并坚持我们在目标C中的习惯。

现在,如果我看一下他们在UITableView定义中的内容,我只会看到:

var dataSource: UITableViewDataSource!
var delegate: UITableViewDelegate!

protocol UITableViewDelegate : NSObjectProtocol, UIScrollViewDelegate {
    [...]
}

我猜这与它实际上只是对Objective C的绑定有关,而且客观C定义可能优先于swift定义,但我在文档中找不到官方解释。

1 个答案:

答案 0 :(得分:3)

这是因为一般来说很多Cocoa代表都不弱。 Cocoa的大部分都不是用ARC编写的 - 因为它们先于它。他们正在手动管理内存,就像我们过去常常要做的那样。所以他们没有得到ARC弱的乐趣(这是weak在这里指出的)。它们使用纯的,非内存管理的委托(和数据源)分配。他们没有保留它,所以没有保留周期;但由于他们没有使用ARC,因此它们不具备防撞保护功能。

因此,在主要实例的生命周期内,不要让这样的委托不再存在你的责任,以免它试图向悬空指针发送消息并崩溃。

你可以通过实验看到这一点(这是Objective-C,但你很容易看出这一点):

self->_obj = [NSObject new];
nav.delegate = self->_obj // nav is our navigation controller, the root view controller
dispatch_async(dispatch_get_main_queue(), ^{
    // cry havoc, and let slip the dogs of war!
    self->_obj = nil; // releases obj - now what is nav.delegate pointing to??
    NSLog(@"Nav Controller delegate: %@", ((UINavigationController*)self.window.rootViewController).delegate); // if you're lucky it might print something!
    // or more likely it will just crash, or maybe print and *then* crash
});

这种崩溃正是ARC弱者所阻止的,因为它会自动将nilling指针替换为nil - 而在Objective-C中,nil的消息是无害的。