Note that there are some explanatory texts on larger screens.

plurals
  1. PONSMutableDictionary sets objects incorrectly
    primarykey
    data
    text
    <p>I have a singleton class where I set up a <code>NSMutableDictionary</code> called <code>completedLevels</code>.</p> <p>This is how I set it up (in the <code>init</code> method of my singleton): </p> <pre><code> NSString *mainPath = [[NSBundle mainBundle] bundlePath]; NSString *levelConfigPlistLocation = [mainPath stringByAppendingPathComponent:@"levelconfig.plist"]; NSDictionary *levelConfig = [[NSDictionary alloc] initWithContentsOfFile:levelConfigPlistLocation]; completedLevels = [[NSMutableDictionary alloc]init]; NSMutableDictionary *levelSets = [[NSMutableDictionary alloc]init]; NSMutableDictionary *levels = [[NSMutableDictionary alloc]init]; NSMutableDictionary *stats = [[NSMutableDictionary alloc]init]; [stats setObject:[NSNumber numberWithBool:NO] forKey:@"levelDone"]; [stats setObject:[NSNumber numberWithInt:0] forKey:@"stars"]; [stats setObject:[NSNumber numberWithInt:0] forKey:@"time"]; [stats setObject:[NSNumber numberWithInt:0] forKey:@"bestTime"]; for (int i = 1; i&lt;=18; i++) { [levels setObject:stats forKey:[NSString stringWithFormat:@"level%d", i]]; } for(int i= 1; i&lt;=15;i++){ NSString *lvlSet = [NSString stringWithFormat:@"levelSet%d", i]; [levelSets setObject:levels forKey:lvlSet]; } NSArray *categoriesArray = [levelConfig objectForKey:@"categoriesArray"]; for (int i=0; i&lt;[categoriesArray count]; i++) { NSString *category = [[levelConfig objectForKey:@"categoriesArray"]objectAtIndex:i]; [completedLevels setObject:levelSets forKey:category]; } </code></pre> <p>I want to explain my doings: </p> <p>My intention was to create a dictionary in this form: </p> <pre><code> category = { levelSet1 ={ level1 ={ bestTime = 0; levelDone = 0; stars = 0; time = 0; }; level2={ bestTime = 0; levelDone = 0; stars = 0; time = 0; }; . . . } levelSet2 ={ level1 ={ bestTime = 0; levelDone = 0; stars = 0; time = 0; }; level2={ bestTime = 0; levelDone = 0; stars = 0; time = 0; }; . . . } . . . } </code></pre> <p>%d in the case of levelSet are integers from 1 to 15.</p> <p>%d in the case of level are integers from 1 to 18. </p> <p>I have several categories, and thus multiple sets of the example above.</p> <p>This works well and upon calling NSLog, the dictionary appears in my console as it should. The problem, however, arises when I want to change some entries in my dictionary as shown in the example below: </p> <pre><code> NSString *category = [[GameStateSingleton sharedMySingleton]getCurrentCategory]; NSString *levelSet = [NSString stringWithFormat:@"levelSet%d",[[GameStateSingleton sharedMySingleton]getSharedLevelSet]]; NSNumber *currentLevel = [NSNumber numberWithInt:[[GameStateSingleton sharedMySingleton]getSharedLevel]]; NSString *levelString = [NSString stringWithFormat:@"level%d", [currentLevel intValue]]; NSMutableDictionary *categories = [[NSMutableDictionary alloc]initWithDictionary: [[GameStateSingleton sharedMySingleton]getCompletedLevels]]; [[[[categories objectForKey:category]objectForKey:levelSet]objectForKey:levelString]setObject:[NSNumber numberWithBool:YES] forKey:@"levelDone"]; [[GameStateSingleton sharedMySingleton]setCompletedLevels:categories]; NSLog(@"%@",[[GameStateSingleton sharedMySingleton]getCompletedLevels]); </code></pre> <p>To explain that: </p> <p>When the player is done with a level, I want the <code>levelDone</code> entry to change its value. But when I log it afterwards, suddenly all <code>levelDone</code> entries of all categories change to the BOOLEAN value of 1. Why is that ?</p> <p><strong>------------------- update -----------------------</strong></p> <pre><code>completedLevels = [[NSMutableDictionary alloc]init]; NSMutableDictionary *levelSets = [[NSMutableDictionary alloc]init]; NSMutableDictionary *levels = [[NSMutableDictionary alloc]init]; NSMutableDictionary *stats = [[NSMutableDictionary alloc]init]; [stats setObject:[NSNumber numberWithBool:NO] forKey:@"levelDone"]; [stats setObject:[NSNumber numberWithInt:0] forKey:@"stars"]; [stats setObject:[NSNumber numberWithInt:0] forKey:@"time"]; [stats setObject:[NSNumber numberWithInt:0] forKey:@"bestTime"]; for (int i = 1; i&lt;=18; i++) { NSMutableDictionary *statsCopy = [stats mutableCopy]; [levels setObject:statsCopy forKey:[NSString stringWithFormat:@"level%d", i]]; [statsCopy release]; } for(int i= 1; i&lt;=15;i++){ NSString *lvlSet = [NSString stringWithFormat:@"levelSet%d", i]; NSMutableDictionary *levelsCopy = [levels mutableCopy]; [levelSets setObject:levelsCopy forKey:lvlSet]; [levelsCopy release]; } NSArray *categoriesArray = [levelConfig objectForKey:@"categoriesArray"]; for (int i=0; i&lt;[categoriesArray count]; i++) { NSString *category = [[levelConfig objectForKey:@"categoriesArray"]objectAtIndex:i]; NSMutableDictionary *levelSetsCopy = [levelSets mutableCopy]; [completedLevels setObject:levelSetsCopy forKey:category]; [levelSetsCopy release]; } </code></pre> <p>The part where I retrieve and set it stayed the same... </p> <p><em><strong></em>__<em>_</em>__<em>_</em>__<em>_</em>__<em>_</em>__<em>_</em>__</strong> <strong>SOLUTION</strong> <strong><em>_</em>__<em>_</em>__<em>_</em>__<em>_</em>__<em>_</em>__<em>_</em>____</strong></p> <pre><code>NSMutableDictionary *mutableCopy = (NSMutableDictionary *)CFPropertyListCreateDeepCopy(kCFAllocatorDefault, (CFDictionaryRef)originalDictionary, kCFPropertyListMutableContainers); </code></pre> <p>I made deep-copies with this method. </p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload