简体   繁体   English

iOS内存管理困惑

[英]iOS memory management confused

I have a static method in a Utilities class: 我在实用程序类中有一个静态方法:

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

    return defaultDivision;
}

And in my ViewController I do something like: 在我的ViewController中,我做类似的事情:

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

But when I analyze, it says "Potential leak of an object allocated on line x and stored into defaultDivision". 但是当我分析时,它说“分配给第x行并存储到defaultDivision的对象的潜在泄漏”。

If I use: 如果我使用:

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

it works once, but when I use it again, it crashes. 它可以工作一次,但是当我再次使用它时,它会崩溃。

Just wondering what the proper thing is to do here? 只是想知道在这里应该做什么?

If this is your real code; 如果这是您的真实代码;

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

You're first allocating a Division and saving it in div, then you're getting a new one from getDefaultDivision storing that in div too without releasing the first one. 您首先要分配一个Division并将其保存在div中,然后从getDefaultDivision中获得一个新分区,也将其存储在div中而无需释放第一个分区。

Regardless of how "getDefaultDivision" is implemented, you have a leak in this code: 无论如何实现“ getDefaultDivision”,此代码都存在泄漏:

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

Line 1 allocates memory and assigns div to point to that memory. 第1行分配内存,并分配div指向该内存。 You must free this memory at some point. 必须在某个时候释放此内存。 But after line 2, that becomes impossible, because div is now has a new value -- and the pointer to the memory allocated in line 1 is lost . 但是在第2行之后,这变得不可能了,因为div现在有了一个新值-并且指向第1行中分配的内存的指针丢失了 This is a leak. 这是泄漏。 Until you understand why, you are on thin ice. 除非您了解原因,否则您将陷入困境。

As for this method: 至于这种方法:

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

This is sometimes called a "factory" method -- a static utility method for allocating, initializing, and returning reference to a new instance of a class. 有时称为“工厂”方法-一种静态实用程序方法,用于分配,初始化和返回对类的新实例的引用。 The best practice here is to use autorelease in factory methods. 此处的最佳做法是在工厂方法中使用自动释放。 Eg: 例如:

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

Why is it a best practice? 为什么是最佳做法? According to Apple's memory management guide, only methods with the following terms in them should return references to objects that the caller is responsible for releasing: 根据Apple的内存管理指南,只有其中包含以下术语的方法才应返回对调用者负责释放的对象的引用:

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

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

Since "getDefaultDivision" is not an "alloc" or "copy" method (it is an accessor method), then it should not return a pointer to an object which the caller must later free to avoid a leak. 由于“ getDefaultDivision”不是“ alloc”或“ copy”方法(它是访问器方法),因此它不应返回指向对象的指针,调用者以后必须释放该对象以避免泄漏。 Marking the newly allocated returned memory as autorelease is one way to follow this contract. 将新分配的返回内存标记为自动释放是遵循此合同的一种方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM