使用NSMutableArray后为什么不释放内存

时间:2015-05-01 11:23:20

标签: ios objective-c

我们假设我们使用Xcode创建了一个新的MacOS应用程序,并在[viewDidLoad]中添加了一些代码。

运行后内存未完全释放。为什么?如何释放记忆?

示例代码:

NSMutableArray *a = [NSMutableArray array];

for(int i=0;i<8000000;i++){
    [a addObject:[NSValue valueWithPoint:NSMakePoint(i, 0)]];
}
a = nil;

我可以通过按钮看到有关内存的信息,该按钮的名称是&#34;显示调试导航器&#34;通过Xcode

4 个答案:

答案 0 :(得分:2)

首先让我们看看你做了什么:

NSMutableArray *a = [NSMutableArray array];
for(int i=0;i<8000000;i++){
  [a addObject:[NSValue valueWithPoint:NSMakePoint(i, 0)]];
}
a = nil;

您在自动释放池中创建一个数组,并在自动释放池中创建许多值对象。自动释放的数组包含值对象。

一个。只要有自动释放池,就不会释放任何对象。自动释放池保留它们。因此,将a设置为nil并不会有所帮助。只要autorelease池保留一个对象,放弃私有引用就不能将引用计数设为0。

有两种方法可以避免这种情况:

一个。正如@sunshine所提到的,您可以安装本地自动释放池。这将保留对象而不是更全局的自动释放池,更早地释放对象。 (但正如@HotLicks所说,如果应该放在整个片段之外。)

湾不要在自动释放池中创建对象。

NSMutableArray *a = [NSMutableArray new]; // new is ownership transfer
for(int i=0;i<8000000;i++) {
  CGPoint point = NSMakePoint( i, 0 );
  [a addObject:[[NSValue alloc] initWithBytes:&point withObjCType:withObjCType:@encode(CGPoint)];
}
a = nil;

B中。你可能仍然有#34;幽灵般的&#34;对象。可能这是,因为一些价值类(即NSNumber)确实永远不会释放一些被认为在不久的将来重复使用的对象。使用NSValue时,valueWithPoint:也可以这样做。没有相应的-initWithPoint:是指针。

如果您告诉我们,您可以获得更好的信息,如何衡量内存消耗。 &#34; ARC&#34;这个问题没有答案,因为它是一个内存管理模型,没有内存测量工具。

答案 1 :(得分:1)

如果您正在使用ARC,那么您根本不关心释放。如果在手动内存管理模式下运行此代码,那么在这种情况下您仍然不必担心内存,因为数组及其拥有的对象都是自动释放的。所以这段代码完全正常,不会导致任何内存泄漏

答案 2 :(得分:0)

您可以使用@autoreleasepool:

@autoreleasepool {
    for(int i=0;i<8000000;i++){
        [a addObject:[NSValue valueWithPoint:NSMakePoint(i, 0)]];
    }
}

答案 3 :(得分:0)

使用ARC并不能保证您的对象会被释放或告诉您它们何时被释放。一切都在幕后自动完成。

当我说你的物体不能保证被释放时,请考虑保留(强)循环,即使使用ARC,它们仍然是现实。

所以,你的代码在这一点上很好,但如果你想强制发布,正如同事提到的那样,将你的本地对象嵌入到@autoreleasepool块中,当执行完成时它将被耗尽。