Maciej Chrzastek
Maciej Chrzastek

Reputation: 1490

App crashes when setting objects to NSMutableDictionary with no crash log

I try to make a simple score system for my game and I'm using dictionary and save it using NSUserDefaults to store player's scores. However when I try to set new score to existing key/value the app crash, there isn't any console log message and xcode switches to the unreadable for me assembler code. I know where it crashes because I set exception and it shows on which line it has been called. I also use cocos2d if that change anything.

here's the code:

//creates key for the right level     
NSString *currentLevelString = [NSString stringWithFormat:@"Level%i",numberOfCurentLevel];


 //checking if dictionary is empty, if empty then it means the game is played for the first time
 NSMutableDictionary *dictionary = [[[NSMutableDictionary alloc]init]autorelease];
//ud is the UserDefaults

 dictionary = [ud objectForKey:@"dictionaryWithScores"];

 if ([dictionary objectForKey:@"Level5"] == nil) {
     //assigning first values for empty dictionary
     dictionary = [NSMutableDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle]pathForResource:@"ScoreList" ofType:@"plist"]];
     NSLog(@"dictionary was empty");
 }
 //NSLog(@"now dictionary shoud not be empty %@",dictionary);
 //calculating current score for this level
 double currentScore = (numberOfCurentLevel * elementsFound)/9.0;///timeInSeconds;
 double previousScore = [[dictionary objectForKey:currentLevelString]doubleValue];//taking previous score for thi level
 NSLog(@"currentScore: %f \n previousScore: %f",currentScore,previousScore);
 //checking whether current score is greater than the previous one
 if (currentScore > previousScore)
 {
     NSLog(@"dictionary just before the crash: %@",dictionary);
     //if new score is greater then update the dictionary
     NSString *currentScoreString = [NSString stringWithFormat:@"%f",currentScore];

//it crashes on this line seObject

     [dictionary setObject:currentScoreString forKey:currentLevelString];
     [ud setObject:dictionary forKey:@"dictionaryWithScores"];
     [ud synchronize];

//calculating total score (score for each level + next one)
 double overallScore = 0;
 for (int i=1; i <= 101; i++) {
     //adding scores for each level to each other
     overallScore = overallScore + [[dictionary objectForKey:[NSString stringWithFormat:@"Level%i",i]]doubleValue];
    // NSLog(@"overal score: %f",overallScore);
 }

when I comment the setObject line then everything works fine. Can anyone if there is something that cause the crash? Thank you in advance.

Upvotes: 0

Views: 1948

Answers (1)

Abhi Beckert
Abhi Beckert

Reputation: 33369

Your problem is this line:

dictionary = [ud objectForKey:@"dictionaryWithScores"];

That is returning an immutable dictionary, so there is no setObject: method. You loaded the plist file into a mutable dictionary, but all dictionaries inside that dictionary will still be immutable.

To convert an immutable dictionary to a mutable one, do this:

dictionary = [[ud objectForKey:@"dictionaryWithScores"] mutableCopy];

You probably also want to save the mutable copy you just made back into the ud dictionary:

[ud setObject:dictionary forKey:@"dictionaryWithScores"];

PS: I'm not sure why you don't see a log message; You should see one.

Upvotes: 7

Related Questions