0

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

@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 方法(在 [substring release] 或 [primaryString release] 上)中因 EXC_BAD_ACCESS 信号而崩溃。

我不明白为什么会发生这种情况,因为我相信我遵循了正确的内存管理指南。如果我注释掉 firstItem release 一切都很好。

4

4 回答 4

4

您提到的自动释放方法很好,其他常见的习惯用法也是如此:

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

如果你后来过度释放,就是你的问题。这部分,你显然做得正确,不是问题。

于 2012-06-05T15:45:39.180 回答
1
SomeObject * new_object = [SomeObject alloc] init];
self.object = new_object;
[new_object  release];

或使用 ARC

于 2012-06-05T15:45:36.667 回答
0

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

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

[[NSString alloc] initWith...]

您必须释放或自动释放。

[NSString stringWith...] 

无需释放。

或者像 meggar 说的那样使用 ARC

于 2012-06-06T22:31:30.730 回答
0

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

于 2012-06-08T00:16:44.323 回答