Teach init a 'defer'-like ability to deinit
'defer' is a great way to ensure some clean up code is run; it's declaritive
locality to the resource acquisition is a boon to clarity.
Swift offers no support for resources acquired during 'init'.
For an example, from
https://www.mikeash.com/pyblog/friday-qa-2015-04-17-lets-build-swiftarray.html
init(count: Int = 0, ptr: UnsafeMutablePointer<T> = nil) {
self.count = count
self.space = count
self.ptr = UnsafeMutablePointer<T>.alloc(count)
self.ptr.initializeFrom(ptr, count: count)
}
deinit {
ptr.destroy(...)
ptr.dealloc(...)
}
Another 'resource' might be adding an NSNotificationCenter observer, and
wanting to unobserve in deinit (no need in OS X 10.11, iOS 9, but for earlier
releases this is a valid example).
Changing the above code to use a 'defer' style deinit block might look like:
init(count: Int = 0, ptr: UnsafeMutablePointer<T> = nil) {
self.count = count
self.space = count
self.ptr = UnsafeMutablePointer<T>.alloc(count)
self.ptr.initializeFrom(ptr, count: count)
deinit {
ptr.destroy(...)
ptr.dealloc(...)
}
// NSNotificationCenter example too
NSNotificationCenter.defaultCenter().addObserver(...)
deinit {
NSNotificationCenter.defaultCenter().removeObserver(...)
}
}
The need to provide a separate implemention of deinit is gone. Reasoning for
'defer' applies here. There is good locality between what was initialized and
what needs cleaning up.
Considerations:
1. Should deinit blocks be invoked before or after code in an explicit deinit
method?
2. Should deinit blocks be allowed in other methods; e.g. viewDidLoad()?
3. How should deinit blocks be prevented from strongly capturing self (thus
preventing themselves from ever running!)?
Cheers,
Graham Perks._______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution