On Fri, Jun 10, 2016 at 9:55 PM, Jonathan Hull via swift-evolution <
[email protected]> wrote:
> I really love this idea. My mental model of it is that it is exactly like
> ‘defer’, except it works on the lifetime of the object instance instead of
> a function/method. Same thing, different scope.
>
> I like how the creation and destruction are right next to one another. It
> also solves a lot of potential issues with partial initialization, I
> believe.
>
> I might spell it ‘deferToDeinit’ or 'deferUntilDeinit'
>
> The only issue I see is accidentally capturing self strongly. Is there a
> way to mark a closure as implicitly unowned self so the end programmer
> doesn’t have to worry about it?
>
I really like this idea as well. Does it need to be a regular closure? This
is one of those things that can be built into the language itself, surely?
Then the implicitly unowned self part would be taken care of...
>
> Thanks,
> Jon
>
> Twitter tl;dr:
> >* Brent: So each instance must remember which init was used for it and then
> >run the matching deinit code at deinit time?
> *>* Me: In my version, the constructive act and destructive act are always
> paired, even redundantly, using a stack if needed
> *>* Graham: so all your deferredDeinit blocks would run, no matter which init
> was invoked?
> *>* Brent: Closure stack in the worst case. Might be able to optimize to
> something cheaper if no captures. Degenerate case: `for i in 0..<10 { deinit
> { print(i) }
> *
> So continuing on from Twitter, assuming the compiler cannot optimize in the
> case of multiple inits, and init-redirections, how about allowing traditional
> deinit as well, and introduce compile-time optimization into traditional
> de-init if the compiler finds only one initialization path per class? We can
> also warn anyone using my version in a complicated degenerate way that it can
> be costly through education, manual, etc. It would also help if (especially
> in Cocoa), you could legally use shared initialization setup closures.
>
> If I create an observer, I want to be able to handle its end-of-life at that
> point. If I allocate memory, ditto. Etc etc. Surely Swift should be able to
> support doing this.
>
> -- E
>
> >* On Jun 8, 2016, at 3:43 PM, Erica Sadun via swift-evolution
> ><swift-evolution at swift.org
> ><https://lists.swift.org/mailman/listinfo/swift-evolution>> wrote:
> *> >* 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 at swift.org
> <https://lists.swift.org/mailman/listinfo/swift-evolution>
> <mailto:swift-evolution at swift.org
> <https://lists.swift.org/mailman/listinfo/swift-evolution>>> 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>
>
> <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
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution