据我所知,要在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定义,但我在文档中找不到官方解释。
答案 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的消息是无害的。