Swift UITableView委托和数据源声明并保留周期

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

weak var delegate: TheDelegateProtocol! 

和一个这样的协议:

 @class_protocol protocol TheDelegateProtocol { } 

为了避免保留周期,并坚持我们在目标C中所做的事情。

现在,如果我看看他们在UITableView定义中有什么,我只看到:

 var dataSource: UITableViewDataSource! var delegate: UITableViewDelegate! 

和:

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

我想这与它实际上只绑定到Objective C的事实有关,而且Objective C的定义可能优先于Swift的定义,但我在文档中找不到正式的解释。

这是因为一般来说,许多cocoa代表并不弱。 大部分的cocoa不是用ARC写的 – 因为它们在它之前。 他们正在手动pipe理内存,就像我们以前在过去所做的那样。 所以他们没有得到ARC弱的乐趣(这是什么weak指示在这里)。 他们使用纯粹的,非内存pipe理的委托(和数据源)分配。 他们不保留它,所以没有保留周期; 但由于他们没有使用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-weak防止的,因为它会自动replace悬挂的指针 – 而Objective-C中的消息是无害的。