-
Notifications
You must be signed in to change notification settings - Fork 18
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
Crash on 'Observable.notifyObservers' #28
Comments
Hey! I haven't seen this before no. It looks like it's saying the crash is in NSOperationQueue which is suspicious, because Communicator doesn't use NSOperationQueue (but I imagine WatchConnectivity does under the hood). Communicator just uses closures |
It looks like the crash is related to switching watches, which might help us narrow down the issue. Do you know if this is just happening on iOS 14 with watchOS 7? |
Thanks for your quick reply 🙂 It have actually only happened on iOS version Thanks for helping me get to the bottom of this 👍 |
Is this the only stack trace or are there others? Just trying to understand if it's always after |
Oh also and do you have any observers attached for |
Yes the stack traces looks all the same. I have the following observers: iOSSessionHandler.swift
WatchOSSessionHandler.swift
I have setup several observers for the |
Yep should be totally fine! I'm wondering whether I've implemented watch switching support incorrectly, the docs do say the app will terminate if certain methods aren't implemented when the user switches watches, but could also just be a bug in WatchConnectivity |
Hmm yes that could be a possibility. The weird part is that I don't think it was triggered by a watch switching. I just stumbled upon two new crashes with the following stack trace. It seems like there is an issue with the
|
I've been able to reproduce this; this is a race condition where configuring the callbacks can occur at the same time as one notifying. For example, on thread #0:
So thread #2 and #0 are trying to access and use the observer list at the same time. Ideally observers would be able to be set up before the delegate is set up, so no messages are lost in-between those two points in time. However, adding an observer also explicitly creates the singleton. |
Omg nice find! I think that can be solved by creating the shared instance asynchronously. Good ol' DispatchQueue.main.async to the rescue! |
Possibly also WatchConnectivity might expect us to only access the WCSession on the main thread too but I'll have to check that |
I've been trying to reproduce this race condition in a test case (without using Communicator) so that I can see if there's a nicer way than just using DispatchQueue.main.async but I'm struggling to get a test case to crash. Difficult to get two threads to access the same dictionary at the same time in a test |
Okay using this code I can make some crash although not exactly the same as the ones above, but it is still related to the setter of the dictionary, so that's something. Would be nice to make that work nicely so that we know the crash is fixed. I think it's also right to delay the creation of the shared Communicator instance until the next run of the main queue because it gives you a chance to set up all the observers. Alternatively, I could make it so there's an extra step and you have to initialise the communicator object which is a bit ugly but at least gives more stability func test_raceCondition() {
let group = DispatchGroup()
for _ in 0 ..< 1000 {
group.enter()
DispatchQueue.global().async {
MyThing.observe { thing in }
MyThing.notifyObservers(MyThing())
group.leave()
}
}
group.wait()
} |
Hi @KaneCheshire!
I'm are experiencing new crashes on the
Observable.notifyObservers
function.I have investigated, but I haven't been able to reproduce it. Have you experienced the same thing, or have an idea of where to look, in order to fix this?
Stacktrace
The text was updated successfully, but these errors were encountered: