2

我一直在阅读有关 autoreleasepool 的信息,但有一点对我来说有点不清楚。我有一些使用线程的功能,这些线程需要使用自动释放池进行单独的内存管理。

在下面的例子中是正确的

-(void) doSomething {

   NSAutorelease *pool = [[NSAutorelasepool alloc] init];

   NSString *myString = @"Hello";

   [pool release];
}

它是否正确?

-(void) doSomething {

   NSAutorelease *pool = [[NSAutorelasepool alloc] init];

   NSString *myString = [[NSString alloc] initWithString:@"Hello"];

   [pool release];
}

或这个?

-(void) doSomething {

   NSAutorelease *pool = [[NSAutorelasepool alloc] init];

   NSString *myString = [[NSString alloc] initWithString:@"Hello"];

   [myString release];
   [pool release];
}

我的问题是在自动释放池范围内创建的拥有对象需要专门重新释放,还是在释放自动释放池时得到照顾?

4

4 回答 4

1

自动释放池处理自动释放的对象。如果您拥有一个对象(通过分配或复制或保留),那么您必须释放它。所以你的第二个例子不正确。当您分配了字符串时,您拥有它并且您必须释放它。

为主线程创建一个自动释放池。(如果需要,您可以查看主要功能)。每个线程都需要自己的自动释放池来管理自动释放的对象。这就是为什么如果您创建另一个线程,那么您必须为该线程创建一个自动释放池。即使您不在线程中创建自动释放对象,您也应该创建它,因为该线程中的库调用可能会创建自动释放对象。即使您确定没有库调用正在生成自动释放的对象,那么您也应该创建它们,因为这是最佳实践,特别是如果您正在处理由多人开发和维护的大型项目。

于 2010-11-19T08:29:59.800 回答
0

当您创建一堆要立即进行垃圾收集的自动释放对象时,您只需要创建自己的自动释放池。但是,您是正确的,因为您不想引用在释放池后创建的任何“自动释放”对象。自动释放的对象(您不保留)在池耗尽时被销毁。

由于您的示例中没有任何对象是自动释放的,因此创建自己的自动释放池本质上是无操作的。

于 2010-11-19T08:28:41.923 回答
0

您的两个示例都不需要自动释放池。自动释放池只处理自动释放的对象:

NSArray *foo = [NSArray array];
NSObject *bar = [[[NSObject alloc] init] autorelease];

您的第一个字符串是使用字符串文字初始化的,因此在内存管理方面可能是特殊的(也许其他人知道更多)。你的第二个字符串泄漏,池没有任何区别。您的第三根琴弦已正确释放,泳池再次没有任何区别。

这是你需要一个游泳池的地方:

- (void) someMethodThatRunsOnAThread {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    NSString *foo = [@"foo" uppercaseString];
    [pool drain];
}

foo如果池不存在,这里的字符串会泄漏。请注意,我是在调用drain而不是release在池上调用——在 iOS 上没有区别,但在垃圾收集环境中,两者不同,因此最好养成调用正确的习惯。

另请注意,即使您自己不自动释放任何对象,您也可能需要一个池,在您在方法中调用的代码中的某处可能会执行许多内存操作。

于 2010-11-19T08:29:39.020 回答
0

认为这应该是这样的:

-(void) doSomething {

   NSAutorelease *pool = [[NSAutorelasepool alloc] init];


   NSString *myString = [[[NSString alloc] initWithString:@"Hello"] autorelease];

   // or create string like this (automatically autoreleased)
   NSString *myString = [NSString stringWithString:@"Hello"];

   [pool release];
}

您必须向自动释放池中的对象发送自动释放消息。当释放消息发送到池时,它们将被释放。

于 2010-11-19T08:36:34.637 回答