How do I prevent a retain cycle when passing around functions as objects in Swift
Imagine you have a datasource object like this
import UIKit
class MagicDataSource:NSObject,UITableViewDatasource {
deinit {
println("bye mds")
}
//cant use unowned or weak here
var decorator:((cell:CustomCell)->Void)?
func tableView(tableView:UITableView,cellForRowAtIndexPath indexPath:NSIndexPath)->UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(Identifier, forIndexPath: indexPath) as CustomCell
decorator?(cell)
return cell
}
}
And a view controller like this which has (and wants) a strong ref to that object
import UIKit
class ViewController: UIViewController {
var datasource:MagicDataSource? = MagicDataSource()
deinit {
println("bye ViewCon")
}
override func viewDidLoad() {
super.viewDidLoad()
datasource?.decorator = decorateThatThing
}
func decorateThatThing(cell:CustomCell) {
//neither of these two are valid
//[unowned self] (cell:CustomCell) in
//[weak self] (cell:CustomCell) in
cell.theLabel.text = "woot"
}
}
When you discard the view controller , the datasource will not be released and neither will the view controller as it holds a strong ref to the decorateThatThing
function on the view controller.
You can stop the cycle and get the decorator to release by doing this in ViewController
but it feels messy
override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(animated)
datasource?.decorator = nil
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
datasource?.decorator = decorateThatThing
}
so the question is how do i declare vars and/or functions to avoid having to teardown the datasource manually so that when the view controller is discarded the associated datasource is released too.