Does autoclosure respect weak'ness of a captured variable?

I'm confused whether in the following example the weakInstance autoclosure captures self weakly and can therefore return nil:

func perform(weakInstance: @autoclosure () -> SomeType?) {
     weakInstance() // <- Can this method return nil?
}

someSource.setEventHandler { [weak self] in 
    perform(weakInstance: self)
}

Is there some technique that would allow to verify in the debugger that self is indeed captured weakly, which can be used in this case and others where exact semantics is not trivial?

Yes. Whenever your event handler is called some time in the future, if self is no longer in memory, perform will be called with nil. You can easily verify it by calling perform using e.g. DispatchQueue.after to delay the call, and deallocate self immediately after.

2 Likes

I was revisiting this code and got back to this question. Now, after re-reading, I realized that my question was not addressed completely.

Whenever your event handler is called some time in the future, if self is no longer in memory, perform will be called with nil .

If self is non-nil at the time perform is called, can I expect autoclosure to not retain self? To give you some context, perform can take minutes to execute and the idea is to not extend lifetime of self and use the result of weakInstance() as a kinda isCancelled:

func perform(weakInstance: @autoclosure () -> SomeType?) {
    guard weakInstance() != nil else { return }
    // calculations...
    guard weakInstance() != nil else { return }
    // calculations...
}