即使我明确地释放它,循环中的NSMutableArray也会泄漏内存

时间:2011-11-17 03:22:57

标签: objective-c macos cocoa

此循环泄漏内存:

int64_t i,verylongnumber;

//misc. code

for(i=0;i<verylongnumber;i++){
    NSMutableArray *myArray = [[NSMutableArray alloc] initWithObjects:
            [NSNumber numberWithLongLong:65535],
            [NSNumber numberWithLongLong:65535],
            [NSNumber numberWithLongLong:65535],
            [NSNumber numberWithLongLong:65535],
            nil];
    [myArray removeAllObjects];
    [myArray release];
}

我已经尝试了一切以防止泄漏记忆,但我做不到。我认为它与NSNumbers有关。我认为它们是自动释放的,但这是否意味着我必须单独释放它们(即使用alloc)?我怎么会这样做?为每个NSNumber创建一个单独的变量并将其插入到数组中?这似乎很多工作。我尝试了[myArray removeAllObjects],但这并没有什么区别。它在我自己的线程内有自己的自动释放池。我不确定这是否有所作为。

修正了它:

我在循环中添加了一个额外的自动释放池:

int64_t i,verylongnumber;

//misc. code

for(i=0;i<verylongnumber;i++){

    NSAutoreleasePool *pool2 = [[NSAutoreleasePool alloc] init];

    NSMutableArray *myArray = [[NSMutableArray alloc] initWithObjects:
            [NSNumber numberWithLongLong:65535],
            [NSNumber numberWithLongLong:65535],
            [NSNumber numberWithLongLong:65535],
            [NSNumber numberWithLongLong:65535],
            nil];
    [myArray release];

    [pool2 drain];
}

3 个答案:

答案 0 :(得分:6)

我会捅这个..

您可以删除[myArray removeAllObjects],因为它是多余的。 NSArray确实保留了它们的对象,但是当阵列本身被释放时它们也会释放它们。

NSNumbers本身是自动释放的。但是,如果你做一个非常大的循环,那么自动释放的内存实际上不会被释放,直到for循环退出并最终运行循环(除非你在某处设置了一个单独的NSAutoreleasePool)。

所以我可以看到当循环迭代时内存使用量会如何增加,但是在完成时它应该释放内存。你是怎么得出你有泄漏的结论的?

答案 1 :(得分:3)

您是否在等待近期

中是否发布对象?

自动释放的对象在不久的将来会在某个时候发布。在上面的例子中,您需要循环很多次才能创建许多对象。它们不会在该代码范围内发布。

在GUI应用程序中,它意味着在运行运行循环时函数返回。在控制台应用程序中,它是在池发布时的。

退房:

http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html

  

自动释放池提供了一种可以发送对象的机制   “延期”发布消息。

关键是延迟点。

编辑:(评论后)

请注意,您可以耗尽游泳池。另一种选择是创建非自动释放的数字(alloc / init)并在长时间运行的循环中显式释放。取决于代码,这可能是合乎需要的,因为耗尽池可以释放延迟发布的对象,该循环/作用域假定的后续代码仍然是延迟的。如果你想控制它,那就控制它。

答案 2 :(得分:1)

NSArray在添加到NSArray时保留对象。这意味着NSArray获得该对象的所有权。当从NSArray或NSArray中删除对象时,对象被释放(引用计数-1)。如果object没有任何其他所有者,则对象将被销毁 以下代码将创建内存泄漏

NSNumber *number = [[NSNumber alloc]initWithFloat:floatValue]; //reference count is 1, you are the owner
[aArray addObject:number] //reference count is 2, aArray is also owner.  

因此,为了消除内存泄漏,你应该释放号码。

 NSNumber *number = [[NSNumber alloc]initWithFloat:floatValue]; //reference count is 1, you are the owner
[aArray addObject:number] //reference count is 2, aArray is also owner. 
[number release]; // reference count is 1, you are not owner og number    

如果要向NSArray添加autorelease对象,则无需释放该对象。当弹出自动释放池时,该对象将失去其所有权  在每个for循环的示例中,创建NSNumber,而旧的仍然在内存中等待自动释放池被释放。