I got sent an error log for an app that I've been working on that is experiencing intermittent crashes, generally after working for a 30+ minutes. The exception received in the log is of the type EXC_CRASH (SIGABRT). I haven't experienced the crash myself, and don't have access to the offending device, so the log is all I have to go after when trying to replicate the problem.
After symbolicating the log, it appears that the culprit is the following bit of code (Thread 0 position 10 in the Error log)
if(oldStatus != _connected) {
for(id<OnlineStatusSubscriber> subscriber in _subscribers) {
[subscriber onlineStatus:self statusChangedTo:_connected];
}
}
specifically
for(id<OnlineStatusSubscriber> subscriber in _subscribers) {
if the line number is to be believed.
And I can't figure out what might be going wrong here.
Subscribers is initialized in the init of the class
_subscribers = [NSMutableArray new];
and never thereafter set to nil.
Listeners get added to _subscribers through this method
- (void)subscribe:(id<OnlineStatusSubscriber>)subscriber {
[_subscribers addObject:subscriber];
}
and every class that calls that method does use the OnlineStatusSubscriber interface and implement the onlineStatus:statusChangedTo: method.
I've added the Error Log to a pastebin: https://pastebin.com/Ux0XRm15
As well as the class in question: https://pastebin.com/NjGcaNxp (where the offending line is line 73)
Never mind. I somehow missed that I was unsubscribing from one of the onlineStatus:statusChangedTo: calls. It wasn't even multi-threading, just a direct path. So stupid.
Problem is fixed by iterating over [_subscribers copy] instead of _subscribers.