iphone - 无法弄清楚如何修复 iPhone 上的内存泄漏

标签 iphone objective-c memory-leaks instruments

我正在运行 Leaks 工具,发现我的 Dictionary mutableDeepCopy 中存在大量泄漏,但我无法弄清楚代码出了什么问题。有什么建议吗?

@interface RootViewController : UIViewController{

  NSDictionary *immutableDictionary;
  NSMutableDictionary *mutableDictionary;
}

这是在 Instruments 中突出显示的代码行

self.mutableDictionary = [self.immutableDictionary mutableDeepCopy];

这是创建字典的可变副本的方法

@interface NSDictionary(MutableDeepCopy)
  -(NSMutableDictionary *)mutableDeepCopy;
@end

这是方法实现,我突出显示了 Leaks 所说的 100% 泄漏的代码

- (NSMutableDictionary *) mutableDeepCopy {
    NSMutableDictionary *dictionaryToReturn = [NSMutableDictionary dictionaryWithCapacity:[self count]];
    NSArray *keys = [self allKeys];

    for(id key in keys) {
        id value = [self valueForKey:key];
        id copy = nil;
        if ([value respondsToSelector:@selector(mutableDeepCopy)]) {
            copy = [value mutableDeepCopy];
        } else if ([value respondsToSelector:@selector(mutableCopy)]) {
            copy = [value mutableCopy]; //This is the Leak
        }
        if (copy == nil) {
            copy = [value copy];
        }
        [dictionaryToReturn setValue:copy forKey:key];
    }
    return dictionaryToReturn;
}

最佳答案

您需要根据 Apple 的 Memory Management Rules 来分析这一点.

从这一行开始:

self.mutableDictionary = [self.immutableDictionary mutableDeepCopy];

我希望 mutableDeepCopy 返回一个我拥有的对象,所以在某些时候我需要释放或自动释放它。例如

NSMutableDeepCopy* temp = [self.immutableDictionary mutableDeepCopy];
self.mutableDictionary = temp;
[temp release];

self.mutableDictionary = [[self.immutableDictionary mutableDeepCopy] autorelease];

所以现在我们需要看看 mutableDeepCopy。因为它的名称中有“copy”,所以它需要返回一个“拥有的”对象,这实际上意味着“忘记”释放返回的对象。当您在第一行中创建返回的对象时,您已经无法做到这一点,因为 DictionaryWithCapacity: 为您提供了一个不属于您的对象。将其替换为

NSMutableDictionary *dictionaryToReturn = [[NSMutableDictionary alloc] initWithCapacity:[self count]];

现在你拥有它了。

让 mutableDeepCopy 遵守规则非常重要,因为这意味着您可以以完全相同的方式处理从 mutableDeepCopy、mutableCopy 和 copy 返回的对象。在所有三种情况下,您都拥有插入到数组中的对象副本。因为你拥有它,所以你必须释放它,否则它就会像你发现的那样泄漏。因此,在循环结束时,您需要

[copy release];

这将阻止泄漏。

关于iphone - 无法弄清楚如何修复 iPhone 上的内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4361231/

相关文章:

java - JSON Builder 导致 Tomcat8 应用程序内存泄漏

c++ - 为什么 electric fence/Valgrind 无法捕获此缓冲区溢出问题?

iphone - 在保持旋转的情况下缩放 UIScrollView 内的 UIImageView

ios - 有效的配置文件不适用于 git 存储库

ios - 是否可以获得PID的启动时间?

objective-c - OSX - 在 WebView 中加载图像

java - 是否可以将 'see' 对象图用于垃圾回收?

iphone - 是否可以增加一个字母,即在 Objective-C 中 A + 1 = B?

iPhone:如何使用它(标签栏 Controller 和导航 Controller )

iphone - iOS : How to Preload Data before Display