I really like this idea. Spatially moving cleanup next to unsafe operations is good practice.
In normal code, I want my cleanup to follow as closely as possible to my unsafe act: let buffer: UnsafeMutablePointer<CChar> = UnsafeMutablePointer(allocatingCapacity: chunkSize) defer { buffer.deallocateCapacity(chunkSize) } (Sorry for the horrible example, but it's the best I could grep up with on a moment's notice) I like your idea but what I want to see is not the deinit child closure in init you propose but a new keyword that means defer-on-deinit-cleanup self.ptr = UnsafeMutablePointer<T>(allocatingCapacity: count) deferringDeInit { self.ptr.deallocateCapacity(count) } Or something. -- E p.s. Normally I put them on the same line with a semicolon but dang these things can be long > On Jun 8, 2016, at 10:54 AM, Graham Perks via swift-evolution > <swift-evolution@swift.org> wrote: > > 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 > > <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!)?
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution