简体   繁体   中英

Swift UITableView delegate and dataSource declaration and retain cycles

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM