Objective C版本,自动释放和数据类型

Mic*_*ael 25 iphone xcode release objective-c retain

我是内存托管代码的新手,但我很清楚这个想法.

在我的应用程序通过XCode中的泄漏工具,我注意到我只需要清理我的自定义对象,但不是动态创建的数组,所以我认为这些数据类型是自动释放的 - 这是有意义的,因为我只需要释放数组我用作具有(保留)它们的属性.

然后我注意到一些奇怪的事情:我在某个初始化的数组上得到了泄漏:

NSMutableArray *removals = [NSMutableArray new];
Run Code Online (Sandbox Code Playgroud)

但不是类似的

NSMutableArray *removals = [NSMutableArray arrayWithCapacity:9];
Run Code Online (Sandbox Code Playgroud)

现在,一个用"new"设置的原因是它可能有0-99个项目,而另一个我知道它总是9个.因为两个数组后来都根据用户传递给同一个方法互动,如果我没有在方法结束时发布,或者如果我做了,则要么是泄漏!

我将第一个数组更改为

NSMutableArray *removals = [NSMutableArray arrayWithCapacity:99];
Run Code Online (Sandbox Code Playgroud)

我没有泄漏,也没有发布任何东西.谁能解释一下?

Joh*_*eek 65

正如指出的内存管理规则,只要你有,你有创建的对象+alloc,+new,-copy,或者-mutableCopy,你拥有它,并负责在某个时候释放出来.(事实上​​,+new它只是简写[[MyClass alloc] init].)正如您所说,通过[NSArray new]不释放来创建数组是一个内存泄漏.但是,如果正确处理此对象,通常可以在某个时刻释放它.例如:

  • 如果该方法使用数组是从所谓的创建数组的方法,那么你应该能够释放数组已经使用之后.如果内部方法需要对数组保持更永久的引用,那么该方法负责发送-retain并最终发送-release到对象.例如:

    - (void)myMethod {
        NSArray *removals = [NSArray new];
        // ...
        [someObject someOtherMethod:removals];
        [removals release];
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • 如果在对象的-init方法中创建了数组,则该-dealloc方法可以在销毁对象时释放它.

  • 如果你需要创建数组,然后从方法中返回它,你就发现了自动释放的发明原因.你的方法的调用方并不负责释放对象,因为它不是一个+alloc,+new,-copy,或-mutableCopy方法,但你需要确保它最终被释放.在这种情况下,您-autorelease在返回对象之前手动调用该对象.例如:

    - (NSArray *)myMethod {
        NSArray *removals = [NSArray new];
        // ...
        return [removals autorelease];
    }
    
    Run Code Online (Sandbox Code Playgroud)

当您通过创建数组时+arrayWithCapacity:,您没有调用其中一个"特殊"方法,因此您不必释放结果.这可能与-autorelease上面的最后一个例子很相似,但不一定如此.(顺便说一下,也可以创建一个空的自动释放的NSMutableArray用[NSMutableArray array];所述方法在NSArray中找到,因此它不会的NSMutableArray下的文档中显示出来,但它会创建一个可变的阵列时,发送到的NSMutableArray类).如果'将从你的方法返回数组,你可以用它作为速记[[[NSMutableArray alloc] init] autorelease]- 但它只是一个捷径.但是,在许多情况下,您可以使用-init或创建对象,+new并在适当的时候手动释放它.


小智 7

这是在幕后实现的事情:

+(NSMutableArray*) new
{
    return [[NSMutableArray alloc] init];
}
Run Code Online (Sandbox Code Playgroud)

+(NSMutableArray*) arrayWithCapacity:(NSNumber)capacity
{
    return [[NSMutableArray alloc] initWithCapacity:capacity] **autorelease**];
}
Run Code Online (Sandbox Code Playgroud)

在第一种情况下,数组仅被分配,您负责取消分配它.相反,arrayWithCapacity已为您自动释放,即使您忘记取消分配也不会导致泄漏.