It’s an interesting idea, but with the workaround you’ve found I wonder if it
might make more sense to just have Unowned<T> and Weak<T> in the standard
library? I’ve already defined these myself to work with a few awkward cases and
to allow entries in collections to be weakly referenced.
I mean it’d be nice to have keyword support too; I wonder if could be made more
flexible, e.g- let us also write things like:
let foo:[weak AnyObject] = …
Externally this would appear as if the array were of type AnyObject?, but
internally the array would have an actual type of Weak<AnyObject> or whatever.
I dunno, just thinking out loud, point being that maybe this isn’t enum
specific, even though enum is an important use-case, i.e- a keyword or global
function could make this easier to do throughout the language.
> On 3 May 2016, at 16:07, Marc Prud'hommeaux via swift-evolution
> <[email protected]> wrote:
>
>
> The following code currently has a retain cycle and memory leak:
>
> enum ParentChild {
> case SonOf(Parent)
> case DaughterOf(Parent)
> }
>
> class Parent {
> lazy var son: Child = Child(parentChild: .SonOf(self))
> lazy var daughter: Child = Child(parentChild: .DaughterOf(self))
> deinit { print("deinit Parent") }
> }
>
> class Child {
> var parentChild: ParentChild
> init(parentChild: ParentChild) {
> self.parentChild = parentChild
> }
> deinit { print("deinit Child") }
> }
>
>
> do {
> let parent = Parent()
> parent.son
> parent.daughter
> }
>
>
> Child.parentChild cannot be declared unowned because ParentChild is a value
> type. I propose adding the ability to declare the reference storage class for
> an enum's associated value, like so:
>
> enum ParentChild {
> case SonOf(unowned Parent)
> case DaughterOf(unowned Parent)
> }
>
> The only current alternative is to have some intermediate reference type that
> itself holds the reference, akin to the old "Box" type that we used to use to
> work around enum limitations. E.g., this is our current cumbersome
> work-around:
>
> /// An unowned reference to a value, which is useful for maintaining
> parent-child relations through value types like enums
> public struct UnownedRef<T: AnyObject> {
> public unowned let value: T
> public init(_ value: T) { self.value = value }
> }
>
> enum ParentChild {
> case SonOf(UnownedRef<Parent>)
> case DaughterOf(UnownedRef<Parent>)
> }
>
>
> class Parent {
> lazy var son: Child = Child(parentChild: .SonOf(UnownedRef(self)))
> lazy var daughter: Child = Child(parentChild:
> .DaughterOf(UnownedRef(self)))
> deinit { print("deinit Foo") }
> }
>
> class Child {
> var parentChild: ParentChild
> init(parentChild: ParentChild) {
> self.parentChild = parentChild
> }
>
> deinit { print("deinit Child") }
> }
>
> The storage type of an enum would, of course, be limited to reference types,
> and when the storage class is weak, it would require that the stored type be
> Optional, just like when declaring a weak variable.
>
> What do people think?
>
> -Marc
>
> _______________________________________________
> 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