【发布时间】:2011-06-17 07:24:08
【问题描述】:
我一定误解了一些内存管理规则,因为当我尝试修复内存泄漏时,应用程序崩溃了。让我给你看一些代码:
calendarRequestLog 是单例对象中 MutableDictionary 类型的属性,只要应用程序运行,它就存在。这是 .h 文件中的声明:
@property (nonatomic, retain, readonly) NSMutableDictionary *calendarRequestLog;
我用 (in init) 分配它:
calendarRequestLog = [[NSMutableDictionary alloc] init];
我用这个填充它(注意保留,这会造成内存泄漏):
[calendarRequestLog setObject:[[NSMutableArray arrayWithObject:delegate] retain] forKey:date];
我有时用这个来访问它:
NSMutableArray* delegates = [calendarRequestLog objectForKey:date];
if(delegates != nil) {
// add delegates
}
我用这个清空它:
NSMutableArray* delegates = [calendarRequestLog objectForKey:date];
if(delegates != nil) {
for (id <ServerCallDelegate> delegate in delegates) { … }
// clear the request from the log
[calendarRequestLog removeObjectForKey:date];
}
这是我删除上面的保留时崩溃的代码:
NSMutableArray* delegates = [calendarRequestLog objectForKey:date];
if(delegates != nil) {
if([delegates containsObject:delegate]) // crash
[delegates removeObject:delegate];
}
它崩溃是因为委托被释放但不是 nil。更准确地说,我得到了一个 EXC_BAD_ACCESS 异常。
所有这些方法都可以以不同的顺序或多次调用。
我不知道为什么会这样。我想,集合应该保留它们的对象——因为这个数组对象(委托)仍然在集合中,它不应该被释放。其他代码不负责任,我给你展示了所有出现的calendarRequestLog。
感谢我能得到的所有帮助!
@编辑 我想我明白了。
我在委托被解除分配时调用崩溃方法,这样我以后就不会在每次事故中调用委托。
但是:我将代表保留在我的 calendarRequestLog 中,因此只要不调用它就无法释放它:
// clear the request from the log
[calendarRequestLog removeObjectForKey:date];
...依次释放委托并调用崩溃方法。由于 calendarRequestLog 已经删除了代表,但还不是 key,所以我们崩溃了。
好的,我会以不同的方式解决这个问题。感谢所有 cmets - 感谢您,我在别处寻找!
【问题讨论】:
-
我没有看到明显的问题。正如您所怀疑的,在 [calendarRequestLog setObject:[[NSMutableArray arrayWithObject:delegate] retain] forKey:date];保留不是必需的。我认为问题出在您未包含的某些代码中。
-
如果没有
-retain,它应该可以工作。您是否绝对确定不会在代码的某些部分中释放该数组,例如[delegates release]? -
我确定 - delegates 始终是一个局部变量,我发布了所有访问 calendarRequestLog 的函数的内容。
-
也许可以提供更多关于崩溃的代码。你使用 delegate 变量...你能保证它总是一个有效的对象还是 nil 吗?
-
@Cit 如果你发现了问题,你应该写下你的解决方案作为答案,并将其标记为下面的答案。
标签: ios iphone objective-c nsmutabledictionary