关于目标 C 中的内存管理



根据静态分析器,如果我们具有以下属性:

@property (retain, nonatomic) SomeObject * object;

然后我们像这样分配属性:

self.object = [SomeObject alloc] init];

发生泄漏。这是有道理的,因为 alloc init 将 +1 添加到保留计数,然后保留属性也会增加保留计数。这里最好的解决方案是什么?通常我只是像这样添加一个自动发布:

self.object = [[SomeObject alloc] init] autorelease];

但有时这会给我带来问题,我最终会过度释放对象,导致我的应用程序崩溃。我现在没有任何具体的例子,但我记得我不得不拿出一些自动发布,因为应用程序崩溃。我在这里缺少什么吗?

编辑:我现在有一个具体的例子来说明我遇到的问题。

    NSMutableArray *newData = [NSMutableArray array];
    //If this is true then we are showing all of the items in that level of hierarchy and do not need to show the summary button.
    if (!(contextID.count >= 1 && [[contextID objectAtIndex:contextID.count - 1] isEqual:[NSNull null]]) && contextID.count != 0)
    {
        GeographyPickerItem * firstItem = [[GeographyPickerItem alloc] init];
        firstItem.primaryString = [NSString stringWithString:@"Summary"];
        firstItem.subString = [NSString stringWithString:@""];
        firstItem.isSummaryItem = YES;
        [newData addObject:firstItem];
        [firstItem release]; //TODO: Figure out why this is causing EXC_BAD_ACCESS errors
    }
    self.hierData = newData;

上面的代码位于视图控制器的 init 方法中。HierData 是一个保留属性,在 viewControllers dealloc 方法中释放。GeographyPickerItem 保留两个字符串,primaryString 和 subString,并在自己的 dealloc 方法中释放它们。我的应用程序崩溃(有时)当视图控制器在导航控制器弹出后取消分配时。它在 GeographyPickerItem 的 dealloc 方法中(在 [子字符串发布] 或 [primaryString release] 上)中出现EXC_BAD_ACCESS信号崩溃。

我不明白为什么会发生这种情况,因为我相信我正在遵循正确的内存管理准则。如果我先注释掉项目发布,一切都很好。

您提到的自动发布方法很好,其他常见的习语也是如此:

SomeObject *thing = [[SomeObject alloc] init];
self.object = thing;
[thing release];

如果你最终在以后过度发布,那就是你的问题。这部分,你显然做对了,不是问题。

SomeObject * new_object = [SomeObject alloc] init];
self.object = new_object;
[new_object  release];

或使用 ARC

检查 GeographyPickerItem,如果字符串属性已分配(并更改为保留),或者检查是否始终初始化它们(在发布之前)。

还要记住手动分配的区别:

[[NSString alloc] initWith...]

您必须发布或自动释放。

[NSString stringWith...] 

无需释放。

或者像梅加尔说的那样使用 ARC。

事实证明问题很简单,我的 dealloc 方法在方法的开头而不是结束时调用了 super dealloc。在调用 [super dealloc] 之前,您始终必须释放实例变量!

最新更新