I'm occasionally getting this crash, which is very hard to reproduce:
0 CoreFoundation 0x39ff73e2 __exceptionPreprocess + 158
1 libobjc.A.dylib 0x3905095e objc_exception_throw + 26
2 CoreFoundation 0x39ffaf2c -[NSObject(NSObject) doesNotRecognizeSelector:] + 180
3 CoreFoundation 0x39ff9648 ___forwarding___ + 388
4 CoreFoundation 0x39f51204 _CF_forwarding_prep_0 + 20
5 Foundation 0x32914bec -[NSDictionary(NSKeyValueCoding) valueForKey:] + 28
6 MyAppName 0x00032112 -[myViewController stopPlayersWithVolume:] (myViewController.m:151)
From this code:
- (void)stopPlayersWithVolume:(double)volume
{
for (NSString *file in players)
{
AVAudioPlayer *player = [players valueForKey:file];
if (player.volume == volume || volume == 0)
[player stop];
}
}
players
is an NSMutableDictionary
property, accessed without self.
because I don't believe it's needed with ARC. The keys are filenames (e.g. "mysound.mp3") and the values are AVAudioPlayer
objects.
Is the stack trace saying that the parameter file
I'm passing to [NSMutableDictionary valueForKey]
is not actually an NSString
, and hence the unrecognised selector? It is always an NSString
in the debugger, as you'd expect as it comes from a fast enumeration through the dictionary, but the crash never occurs in the debugger.
My only thought is that there's a threading issue corrupting the dictionary. The code above is being fired by an NSTimer but that's just a message via the run loop, not a separate thread, so I believe there should be no need to worry about cross-thread access?
Any suggestions appreciated. Sorry to just dump this out but I'm stuck.
Edit:
The players dictionary is allocated in viewDidLoad
thus:
players = [[NSMutableDictionary alloc] init];
And declared as follows:
@property (retain, nonatomic) NSMutableDictionary *players;
And synthesised as follows:
@synthesize players;