Swift UITableView delegate and dataSource declaration and retain cycles

匿名 (未验证) 提交于 2019-12-03 01:34:02

问题:

As far as I understood, to use the delegate pattern in swift I had to declare a property like so:

weak var delegate: TheDelegateProtocol!

And a protocol like so:

@class_protocol protocol TheDelegateProtocol {  }

To avoid retain cycle and stick with what we are used to do in objective C.

Now, if I look at what they have in the UITableView definition, I only see:

var dataSource: UITableViewDataSource! var delegate: UITableViewDelegate!

And:

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

I guess that's related to the fact that it is actually only bindings to Objective C, and the objective C definition might take precedence over the swift definition, but I can't find an official explanation in the documentation.

回答1:

This is for the same reason that in general many Cocoa delegates are not weak. Large parts of Cocoa are not written using ARC - because they precede it. They are managing memory manually, as we used to have to do in the good old days. So they don't get the delights of ARC-weak (which is what weak indicates here). They use pure, non-memory-managed assignment of delegates (and data sources). They don't retain it, so there's no retain cycle; but since they are not using ARC, they are not crash-safe.

Thus it remains your responsibility not to let such a delegate go out of existence during the lifetime of the primary instance, lest it attempt to send a message to a dangling pointer and crash.

You can see this by experimentation (this is Objective-C but you'll readily see the point):

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 });

That kind of crash is exactly what ARC-weak prevents, because it replaces the dangling pointer by nil automatically - and a message to nil, in Objective-C, is harmless.



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!