我很难理解NSAutoReleasePool的工作原理。
1)NSAutoReleasePool是单独跟踪每个分配还是依赖于变量?换句话说,这会泄漏内存还是释放?:
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSArray* myObj = [NSObject alloc];
myObj = [NSObject alloc];
[pool release];
2)为什么以下代码有效:
NSAutoreleasePool *pool1 = [[NSAutoreleasePool alloc] init];
NSArray* myObj = [NSObject alloc];
for(int i = 0; i < 100; i++) {
[myObj release];
myObj = [NSObject alloc];
}
[pool1 release];
,但以下内容为[pool1 release]
提供了EXC_BAD_ACCESS:
NSAutoreleasePool *pool1 = [[NSAutoreleasePool alloc] init];
NSArray* myObj = [NSObject alloc];
NSAutoreleasePool *pool2 = [[NSAutoreleasePool alloc] init];
for(int i = 0; i < 100; i++) {
[myObj release];
myObj = [NSObject alloc];
}
[pool2 release];
[pool1 release];
3)如何使上面的代码工作(带有2个池的代码)?
答案 0 :(得分:5)
自动释放池仅适用于您自动发布的对象。代码中的所有对象都不会自动释放,因此没有任何对象会受到您创建的池的影响。
因此,答案是:
[NSObject alloc]
,那么您的意思是[[[NSObject alloc] init] autorelease]
,那么您的第二个代码示例将会失败,因为您第一次发布myObj
它将是在{{1}之外声明的对象}}。这意味着当您pool2
release
时,它会尝试释放已释放的对象。让它工作的方法是不释放(或自动释放)一个对象多于保留或分配的对象。答案 1 :(得分:2)
NSAutoreleasePool不跟踪分配。当您将消息autorelease
发送到对象时,它会在其线程上搜索自动释放池(一个是通过运行循环在每次行程的顶部自动创建的,并在底部取消分配;在大多数其他例如,你需要手动创建它们)。如果找到一个,则将其添加到自动释放池维护的对象列表中。
当释放自动释放池时,它会将release
消息发送到其列表中的每个项目。如果项目已多次添加到列表中,则会多次释放。
至于你的代码获得EXC_BAD_ACCESS的原因,我不确定。它可能与您未在任何NSObject上调用init
这一事实有关,或者它可能与您尚未向我们展示的代码有关。
答案 2 :(得分:2)
一些事情:
:创建对象时始终使用init方法。 (即[[NSObject alloc] init])
:对象在自动释放时会添加到AutoreleasePool中。此示例中的对象只是被释放,因此根本不会使用自动释放池。你可以通过删除所有自动释放池来看到这一点;代码仍然运行良好。
:第一个例子会泄漏内存。您正在分配两个对象,但从不释放它们。如果你要自动发布它们,那么你可能会得到你正在寻找的行为并且不会有泄漏。
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSArray* myObj = [[[NSObject alloc] init] autorelease];
myObj = [[[NSObject alloc] init] autorelease];
[pool release];
:示例2工作,因为您只是分配,而不是释放对象;其中没有一个使用自动释放池。您可以删除自动释放代码以查看此内容。
:我无法复制您在示例3中看到的行为。也许您的代码中还有其他内容。