Getting intermittent crash with [unowned self]

Hi


I thought I was doing the right thing putting [unowned self] in a closure that references self and is stored in an object that is a property of the object


   private var tableHandler: DataTableHandler?

    override public func viewDidLoad()
    {
        super.viewDidLoad()
        setFittingHeight(self)
        if let records = records {
            records.load()
            let tableHandler = DataTableHandler(cellIndentifier: recordCellIdentifier, array: records)
            tableHandler.tableView = recordsTableView
            tableHandler.afterSelect =
                { [unowned self] _ in self.dismissViewControllerAnimated(true, completion: nil) }
            self.tableHandler = tableHandler
            recordsTableView.reloadData()
        }
        editingChanged(newRecordTextField)
    }// viewDidLoad


But every so often, at the [unowned self] line I get a crash, with 1 swift_unknownRetainUnowned and 0 _swift_abortRetainUnowned appearing on the stack of Thread 1.


Can anyone see what the problem might be?


I'm using XCode 6.4


Regards

Mark

Replies

I'm guessing that it's a race between the deinit of self and self.tableHandler, or a leak of tableHandler. What you might try, to see if it clears things up, is override deinit {} of the self in question:


deinit {
     self.tableHandler.afterSelect = nil
     self.tableHandler = nil
}


That should ensure that the table handler's afterSelect block won't be called after self is gone...

Thanks. I tried that but it didn't work, the crash would still happen if I persistently brought up the offending VC and closed it. To get the syntax right it ended up looking like this:


    deinit {
        self.tableHandler?.afterSelect = { _ in }
        self.tableHandler = nil
    }




But it got me thinking: unowned seems to incur the risk of a stale pointer. I found this, and changed the unowned to weak, and after that I was unable to get it to crash again:

http://stackoverflow.com/questions/24468336/how-to-correctly-handle-weak-self-in-swift-blocks-with-arguments


Using weak effectively make self an optional variable that gets nilled when the object is destroyed. That seems to be what I need in this case.

Regards

Mark