简体   繁体   English

NSAutoreleasePool EXC_BAD_ACCESS和有关Objective-C中的内存管理的问题

[英]NSAutoreleasePool EXC_BAD_ACCESS & Questions About Memory Management in Objective-C

I have difficulties understanding how NSAutoReleasePool works. 我很难理解NSAutoReleasePool的工作方式。

1) Does NSAutoReleasePool keep track of each allocation separately or does it work variable dependent? 1)NSAutoReleasePool是分别跟踪每个分配还是它工作依赖于变量? In other words, does this leak memory or release both?: 换句话说,这是泄漏内存还是释放内存?

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];  
 NSArray* myObj = [NSObject alloc];  
 myObj = [NSObject alloc];  
 [pool release];

2) Why does the following code work: 2)为什么以下代码有效:

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

 NSArray* myObj = [NSObject alloc];

 for(int i = 0; i < 100; i++) {
  [myObj release];
  myObj = [NSObject alloc];
 }

 [pool1 release];

but the following gives EXC_BAD_ACCESS at [pool1 release] : 但是以下内容在[pool1 release] pool1 [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) How can I make the code above work(the one with the 2 pools)? 3)如何使上面的代码起作用(一个有2个池)?

Autorelease pools only works for objects that you autorelease. 自动释放池仅适用于您自动释放的对象。 None of the objects in your code are autoreleased and so none are affected by the pools that you created. 您代码中的所有对象均不会自动释放,因此您创建的池也不会影响它们。

Therefore, the answers are: 因此,答案是:

  1. It leaks both objects (since neither are either released or autoreleased) 它泄漏两个对象(因为都没有释放或自动释放)
  2. It doesn't. 没有。 It leaks the last object allocated 泄漏最后分配的对象
  3. The documentation says that you can nest them . 文档说您可以嵌套它们 If I assume that where you have [NSObject alloc] you really mean [[[NSObject alloc] init] autorelease] then your second code sample will fail because the very first time you release myObj it will be for an object declared outside pool2 . 如果我以为[NSObject alloc][[[NSObject alloc] init] autorelease]那么第二个代码示例将失败,因为第一次释放myObj ,它将是针对在pool2外部声明的对象。 This means that when you release pool1 it tries to release an object that has already been released. 这意味着当您release pool1它将尝试释放已经释放的对象。 The way to get it working is to not release (or autorelease) an object more times than it's retained or allocated. 使它工作的方法是不释放(或自动释放)对象超过其保留或分配的次数。

NSAutoreleasePool does no tracking of allocations. NSAutoreleasePool不跟踪分配。 When you send the message autorelease to an object, it searches for an autorelease pool on its thread (one is created for you automatically at the top of each trip through the run loop, and deallocated at the bottom; in most other cases, you need to manually create them). 将消息autorelease发送给对象时,它会在其线程上搜索一个自动释放池(在运行循环的每次行程的顶部为您自动创建一个释放池,并在底部将其释放;在大多数情况下,您需要手动创建它们)。 If it finds one, then it is added to a list of objects that the autorelease pool maintains. 如果找到一个,则将其添加到自动释放池维护的对象列表中。

When an autorelease pool is deallocated, it sends the release message to each item in its list. 释放自动释放池后,它将release消息发送到列表中的每个项目。 If an item has been added to the list multiple times, it is released multiple times. 如果某项已多次添加到列表中,则会多次释放。

As to why your code gets an EXC_BAD_ACCESS, I am unsure. 至于为什么您的代码得到EXC_BAD_ACCESS,我不确定。 It may have something to do with the fact that you have not called init on any of your NSObjects, or it may have to do with code that you have not yet shown us. 这可能与您尚未在任何NSObjects上调用init有关,或者与尚未显示给我们的代码有关。

A few things: 一些东西:

:When creating objects always make use of an init method. :创建对象时,请始终使用init方法。 (ie, [[NSObject alloc] init]) (即[[NSObject alloc] init])

:Objects get added to an AutoreleasePool when they are autoreleased. :对象在自动释放时被添加到AutoreleasePool中。 The objects in this example are simply being released and so will not use the autorelease pools at all. 本示例中的对象只是被释放,因此根本不会使用自动释放池。 You can see this by removing all the autorelease pools; 您可以通过删除所有自动释放池来看到此情况。 the code still functions fine. 该代码仍然可以正常工作。

:The first example will leak memory. :第一个示例将泄漏内存。 You are allocating two objects and never releasing either. 您正在分配两个对象,并且从不释放任何一个。 If you were to autorelease them, then you would probably be getting the behavior you are looking for and there would not be a leak. 如果要自动释放它们,则可能会得到所需的行为,并且不会泄漏。

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSArray* myObj = [[[NSObject alloc] init] autorelease];
myObj = [[[NSObject alloc] init] autorelease];
[pool release];

:Example 2 works, because you are just allocating, than releasing objects; :示例2起作用,因为您只是分配而不是释放对象; none of which are making use of the autorelease pool. 都没有利用自动释放池。 You can remove the autorelease code to see this. 您可以删除自动发布代码以查看此信息。

:I have been unable to replicate the behavior you are seeing on Example 3. Perhaps there is something else going on inside your code. :我无法复制您在示例3上看到的行为。也许您的代码内还有其他情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM