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

Reply via email to