我在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];
它可以工作一次,但是当我再次使用它时,它会崩溃。
想知道在这里做什么是正确的?
答案 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:
由于“getDefaultDivision”不是“alloc”或“copy”方法(它是一种访问器方法),因此它不应该返回一个指向一个对象的指针,调用者必须在该对象之后自由地避免泄漏。将新分配的返回内存标记为自动释放是遵循此合同的一种方式。