我们假设我们使用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
答案 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
块中,当执行完成时它将被耗尽。