当前位置 : 主页 > 手机开发 > ios >

ios – NSDictionary释放触发valueForKey返回值释放

来源:互联网 收集:自由互联 发布时间:2021-06-11
我目前正在尝试自己进入iOS开发.现在我无法理解内存管理. 这是我混淆的原因: NSString *path = [self.dataPath stringByAppendingPathComponent:@"dummy.plist"];NSMutableDictionary *dict = [[NSMutableDictionary alloc
我目前正在尝试自己进入iOS开发.现在我无法理解内存管理.
这是我混淆的原因:

NSString *path = [self.dataPath stringByAppendingPathComponent:@"dummy.plist"];
NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithContentsOfFile:path];
NSString *dummyKeyValue = [dict valueForKey:@"dummyKey"];

// NSLog(@"%@",[NSString stringWithString:dummyKeyValue]);

[dict release];

NSString *anotherString = [dummyKeyValue lowercaseString];

这段代码在最后一行触发EXC_BAD_ACCESS错误.似乎是因为NSDictionary发布了其关键值.我不明白为什么不考虑dummyKeyValue定义,因为显然dummyKeyValue仍然指向“dummyKey”的值.

现在,当您注释掉NSLog行时,会出现下一个问题,甚至更有趣的现象.以某种方式使用dummyKeyValue似乎可以防止释放它指向的内存.为什么?

感谢帮助!

在手动引用计数模式中,简单地定义变量并不意味着变量指向的对象将自动保留.当dict被释放时,它会释放它的值对象,如果没有其他对象强烈引用它们(即它们的引用计数现在为0),它们就会被释放.这就是你在这里看到的.

如果你想保持对dummyKeyValue的强引用,你需要在收到它后保留它.当然,这也意味着你需要在完成后释放它.试试这个:

NSString *dummyKeyValue = [[[dict valueForKey:@"dummyKey"] retain] autorelease];

现在,dummyKeyValue将一直存在,直到当前自动释放池范围结束.通常,在返回值之前,会编写访问器方法来执行此操作以避免您所看到的情况.

值得注意的是,如果您使用ARC(自动引用计数),您将不会遇到此问题,因为编译器会插入必要的保留/释放调用以确保dummyKeyValue在您完成之前一直存在.

网友评论