Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SR-9000] of deinitializers, property observers, and defer #51503

Open
mattneub opened this issue Oct 15, 2018 · 4 comments
Open

[SR-9000] of deinitializers, property observers, and defer #51503

mattneub opened this issue Oct 15, 2018 · 4 comments
Labels
compiler The Swift compiler in itself improvement

Comments

@mattneub
Copy link

Previous ID SR-9000
Radar None
Original Reporter @mattneub
Type Improvement
Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Improvement
Assignee None
Priority Medium

md5: 659d8175f6537ca6db993b3627e234f6

is duplicated by:

  • SR-10207 Immediate execution of defer warning shouldn't be given in a direct-to-storage context

relates to:

  • SR-1437 defer block in init triggers property observers

Issue Description:

The property observer here never fires:

class A {}
class C {
    var a: A? {
        didSet { print("didset") }
    }
    deinit {
        print("deinit")
        self.a = nil
    }
}
class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        var c : C? = C()
        c = nil
        _ = c
    }
}

Okay, I can accept that; it isn't documented AFAIK, but it makes sense that we wouldn't want to run property observers during deinit, lest there be side effects. But now hold my beer and watch this:

class A {}
class C {
    var a: A? {
        didSet { print("didset") }
    }
    deinit {
        print("deinit")
        defer {
            self.a = nil
        }
    }
}
class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        var c : C? = C()
        c = nil
        _ = c
    }
}

The observer is called! Okay, that is incoherent. If it's wrong to call property observers during deinit, it is really wrong to call property observers after deinit.

@hamishknight
Copy link
Collaborator

Related SR for defer blocks in initialisers not doing direct accesses: https://bugs.swift.org/browse/SR-1437

@mattneub
Copy link
Author

@hamishknight Excellent, thanks; I'd say that's related but not identical.

@hamishknight
Copy link
Collaborator

@mattneub Sure – though in the compiler it's the same logic that determines whether or not to perform a direct access, so ideally a fix for one would also be a fix for the other (that is, depending on compatibility implications – I believe the defer-within-init to trigger observers pattern is used by quite a few people).

@belkadan
Copy link
Contributor

Right. defer probably shouldn't have this behavior, but of course any method you call during deinit will result in the observers running, so it's not like it's not allowed at all.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler The Swift compiler in itself improvement
Projects
None yet
Development

No branches or pull requests

3 participants