iOS内存管理困惑

时间:2012-01-10 21:27:28

标签: ios memory-leaks memory-management

我在Utilities类中有一个静态方法:

+ (Division *) getDefaultDivision
{
    Division *defaultDivision = [[Division alloc] init];
    defaultDivision.Id = 0;
    defaultDivision.name = @"Accounting";
    defaultDivision.slug = @"accounting";

    return defaultDivision;
}

在我的ViewController中,我做了类似的事情:

Division *div = [[Division alloc] init];
div = [Utilities getDefaultDivision];

但是当我分析时,它说“在x行分配的对象的潜在泄漏并存储在defaultDivision中”。

如果我使用:

Division *defaultDivision = [[[Division alloc] init] autorelease];

它可以工作一次,但是当我再次使用它时,它会崩溃。

想知道在这里做什么是正确的?

2 个答案:

答案 0 :(得分:3)

如果这是您的真实代码;

Division *div = [[Division alloc] init];
div = [Utilities getDefaultDivision];

你首先分配一个分区并将其保存在div中,然后你从getDefaultDivision获得一个新的分区,而不是在释放第一个分区的情况下将其存储在div中。

答案 1 :(得分:1)

无论如何实施“getDefaultDivision”,您都会在此代码中泄漏:

Division *div = [[Division alloc] init];
div = [Utilities getDefaultDivision];

第1行分配内存并指定div指向该内存。您必须在某个时刻释放此内存。但是在第2行之后,这变得不可能,因为div现在有一个新值 - 并且指向第1行中分配的内存的指针丢失。这是一个泄漏。直到你明白为什么,你才处于困境之中。

至于这种方法:

+ (Division *) getDefaultDivision
{
    Division *defaultDivision = [[Division alloc] init];
    defaultDivision.Id = 0;
    defaultDivision.name = @"Accounting";
    defaultDivision.slug = @"accounting";
    return defaultDivision;
}

这有时称为“工厂”方法 - 一种静态实用工具方法,用于分配,初始化和返回对类的新实例的引用。这里的最佳实践是在工厂方法中使用自动释放。 E.g:

Division *defaultDivision = [[[Division alloc] init] autorelease];

为什么这是最佳做法?根据Apple的内存管理指南,只有包含以下术语的方法才能返回对调用者负责释放的对象的引用:

alloc, allocWithZone:, copy, copyWithZone:, mutableCopy, mutableCopyWithZone:

- 来自http://developer.apple.com/library/IOs/#documentation/General/Conceptual/DevPedia-CocoaCore/MemoryManagement.html

由于“getDefaultDivision”不是“alloc”或“copy”方法(它是一种访问器方法),因此它不应该返回一个指向一个对象的指针,调用者必须在该对象之后自由地避免泄漏。将新分配的返回内存标记为自动释放是遵循此合同的一种方式。