我目前正在尝试自己进入iOS开发.现在我无法理解内存管理. 这是我混淆的原因: NSString *path = [self.dataPath stringByAppendingPathComponent:@"dummy.plist"];NSMutableDictionary *dict = [[NSMutableDictionary alloc
这是我混淆的原因:
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在您完成之前一直存在.