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-14815] Regression (Linux): NotificationCenter silently failing since 5.4.1 #3218

Open
mickeyl opened this issue Jun 23, 2021 · 6 comments

Comments

@mickeyl
Copy link

mickeyl commented Jun 23, 2021

Previous ID SR-14815
Radar rdar://problem/79653034
Original Reporter @mickeyl
Type Bug
Environment

Swift 5.4, Ubuntu 20.x

Additional Detail from JIRA
Votes 0
Component/s Foundation
Labels Bug
Assignee None
Priority Medium

md5: cb6a9bc2b9d5e55753c5d7918a8daec1

Issue Description:

Please see the following example program:

import Foundation

class Adapter {

    enum State {
        case created
        case searching
        case notfound
        case present
        case gone
    }

    public static let DidUpdateState = Notification.Name("Adapter.DidUpdateState")

    public private(set) var state: State = .created {
        didSet {
            NotificationCenter.default.post(name: Self.DidUpdateState, object: self)
        }
    }

    func doSomething() {
        self.updateState(.searching)
    }
}

extension Adapter {

    func updateState(_ next: State) {
        guard self.state != next else {
            return
        }
        self.state = next
    }
}

class ConcreteAdapter: Adapter {

    override init() {
        super.init()
        NotificationCenter.default.addObserver(forName: Self.DidUpdateState, object: self, queue: nil) { n in
            print("Success: Notification did arrive!")
        }
        print("subscription done")
    }
}

let adapter = ConcreteAdapter()
adapter.doSomething()

print("exiting program...")

On Apple-platforms, this prints `Success: Notification did arrive!` – on Linux, it doesn't.

@weissi
Copy link
Member

weissi commented Jun 23, 2021

@swift-ci create

@weissi
Copy link
Member

weissi commented Jun 23, 2021

Cc @millenomi

@swift-ci
Copy link
Contributor

Comment by Helge Heß (JIRA)

This is missing two things:

  • `Adapter` needs to inherit from `NSObject` (otherwise casting crash at runtime)

  • the subscription token returned by `addObserver` needs to be stored, otherwise the subscription is immediately discarded

With those fixes it runs.

@mickeyl
Copy link
Author

mickeyl commented Jun 23, 2021

Interestingly this seems to be a regression in Swift 5.4. Swift 5.3 warns you through a runtime crash that something is wrong, while Swift 5.4 just fails silently.

@swift-ci
Copy link
Contributor

Comment by Helge Heß (JIRA)

Just to clarify:

The missing subscription storage is properly reported in both 5.3.1 and 5.4.1.

What is different is the `NSObject` fix, 5.3.1 complains about it at runtime:
```
root@a0e1f63ce52e:/tmp# ./test
Could not cast value of type 'test.ConcreteAdapter' (0x55936587d158) to 'Foundation.NSObject' (0x7fb617a5fbc8).
Aborted
```

But in 5.4.1 just nothing happens if the adapter does not inherit from NSObject. Actually you'd think the compiler would already complain in `addObserver` in both cases (i.e. why is the `object` on Linux `Any` if `NSObjectProtocol` is required).

@mickeyl
Copy link
Author

mickeyl commented Nov 9, 2021

Same behavior in 5.5.1.

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

No branches or pull requests

3 participants