Lazy NSObject + deinit = trap

Found an interesting foot-gun (only traps with NSObject classes and only with Foundation on Apple platforms):

import Foundation

class C: NSObject {
    lazy var foo: Int = {
        // Thread 1: abort with payload or reason
        // Cannot form weak reference to instance (0x1007e24f0) of class C.
        // It is possible that this object was over-released, or is in the process of deallocation.
        weak var y: C? = self
        return 1
    }()
    deinit {
        _ = foo
    }
}

do { _ = C() }
print("ended")

The question is whether this should not trap. Or trap in all cases (including non NSObject and non Apple platforms).

3 Likes