NSMutableDictionary 奇怪的问题
Posted
技术标签:
【中文标题】NSMutableDictionary 奇怪的问题【英文标题】:NSMutableDictionary weird problem 【发布时间】:2011-03-07 07:26:09 【问题描述】:假设我有一个包含两个 NSMutableDictionary 的类。
@interface GameDataManager : CCNode
NSMutableDictionary *worldInfoDictionary;
NSMutableDictionary *levelInfoDictionary;
@property (nonatomic, retain) NSMutableDictionary *worldInfoDictionary;
@property (nonatomic, retain) NSMutableDictionary *levelInfoDictionary;
当应用程序这样启动时,我从 plist 加载数据:
-(BOOL) readApplicationData:(NSString *)fileName
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *appFile = [documentsDirectory stringByAppendingPathComponent:fileName];
NSData *myData = [[[NSData alloc] initWithContentsOfFile:appFile] autorelease];
if (myData == nil)
return NO;
NSKeyedUnarchiver *un = [[NSKeyedUnarchiver alloc] initForReadingWithData:myData];
NSMutableDictionary *dic = [un decodeObjectForKey:@"GameData"];
self.worldInfoDictionary = [dic objectForKey:@"WorldInfoDictionary"];
self.levelInfoDictionary = [dic objectForKey:@"LevelInfoDictionary"];
for (int i = 1; i <= 10; i++)
WorldInfoData * w = [worldInfoDictionary objectForKey:
[[[NSString alloc] initWithFormat:@"World%d", i] autorelease]];
NSLog(@"%d", w.worldNum);
[w release];
[un finishDecoding];
[un release];
return YES;
在接下来的两行之后:
self.worldInfoDictionary = [dic objectForKey:@"WorldInfoDictionary"];
self.levelInfoDictionary = [dic objectForKey:@"LevelInfoDictionary"];
我可以看到两个字典中的值/键的数量是正确的。
然后我尝试打印出每个对象的所有“worldNum”值,但应用程序除外 崩溃:
2011-03-07 15:18:21.819 [1267:207] 1
2011-03-07 15:18:21.820 [1267:207] 2
2011-03-07 15:18:21.821 [1267:207] 3
2011-03-07 15:18:21.823 [1267:207] 4
2011-03-07 15:18:21.831 [1267:207] 5
2011-03-07 15:18:21.832 [1267:207] 6
2011-03-07 15:18:21.832 [1267:207] 7
2011-03-07 15:18:21.833 [1267:207] 8
2011-03-07 15:18:21.834 [1267:207] 9
2011-03-07 15:18:21.834 [1267:207] 10
Stack dump:
0. Running pass 'Sparse Conditional Constant Propagation' on function '@gleLLVMVecProjectionTransform2'
如果我取消注释这一行:
[un release];
应用运行良好,没有崩溃。
谁能给我解释一下,非常感谢^_^
感谢大家的回答。
但是如果我删除我用来输出一些信息的代码行:
for (int i = 1; i <= 10; i++)
WorldInfoData * w = [worldInfoDictionary objectForKey:
[[[NSString alloc] initWithFormat:@"World%d", i] autorelease]];
NSLog(@"%d", w.worldNum);
[w release];
并取消注释“[un release];”行,readApplicationData 工作正常, 但是当我稍后尝试像这样读取数据时:
NSMutableDictionary *dic = [GameDataManager sharedGameDataManager].worldInfoDictionary;
for (int i = 1; i <= 10; i++)
NSString *key = [[NSString alloc] initWithFormat:@"World%d", i];
WorldInfoData *worldInfoData = [dic objectForKey:key];
if (worldInfoData.worldNum == 1)
//......
[key release];
在这一行之后:“WorldInfoData *worldInfoData = [dic objectForKey:key];”,worldInfoData 的类型 不是 WorldInfoData * 而是 CCArray,因为 CCArray 没有属性 worldNum,它崩溃了......
【问题讨论】:
finishDecoding 函数里有什么? 那是NSKeyedUnarchiver的一个功能... 【参考方案1】:首先,我建议在启用僵尸检测的情况下运行您的应用程序。
你会发现你正在过度释放 'w' 的通知。
WorldInfoData * w = [worldInfoDictionary objectForKey:
[[[NSString alloc] initWithFormat:@"World%d", i] autorelease]];
NSLog(@"%d", w.worldNum);
[w release];
您将“w”添加到自动释放池中,然后显式调用释放。我猜想摆脱 [w release];行将解决您的问题或不将“w”添加到自动释放池中。
【讨论】:
几乎......被明确自动释放的东西是关键。但是当w
不是此代码拥有的对象时,它会被释放。以上是关于NSMutableDictionary 奇怪的问题的主要内容,如果未能解决你的问题,请参考以下文章
将 NSMutableDictionary 保存到 plist 问题中
将 NSMutableDictionary 的键/值存储到另一个 NSMutableDictionary
如何将 NSArray 添加为 NSMutableDictionary 的 NSMutableDictionary 键?