我一直在阅读关于自动释放池的内容,但有一点对我来说有点不清楚。我有一些使用线程的功能,需要使用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];
}
我的问题是在自动释放池范围内创建的拥有对象需要专门进行关联,还是在autorelasepool被释放时需要处理?
张志贤
答案 0 :(得分:1)
自动释放池处理自动释放的对象。如果您拥有一个对象(通过alloc或copy或retain),那么您必须释放它。所以你的第二个例子不正确。由于您已经分配了字符串,因此您拥有该字符串并且必须将其释放。
为主线程创建自动释放池。 (如果需要,您可以查看主要功能)。每个线程都需要自己的自动释放池来管理自动释放的对象。这就是为什么如果你创建另一个线程,那么你必须为该线程创建一个自动释放池。即使你没有在线程中创建自动释放的对象,你应该创建它,因为该线程中的库调用可能会创建自动释放的对象。即使您确定没有库调用正在制作自动释放的对象,那么您也应该创建它们,因为这是最佳实践,特别是如果您正在处理由多人开发和维护的大型项目。
答案 1 :(得分:0)
您只需要在创建一堆时创建自己的自动释放池 想要立即垃圾收集的自动释放对象。但是,您是正确的,因为您不想引用在释放池后创建的任何“自动释放”对象。当池耗尽时,自动释放的对象(你没有保留)会被销毁。
由于示例中没有任何对象是自动释放的,因此创建自己的自动释放池本质上是无操作。
答案 2 :(得分: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上没有区别,但在垃圾收集环境中两者不同,所以最好养成调用的习惯正确的。
另请注意,即使您不自行自动发布任何对象,也可能需要一个池,可能会在您在方法中调用的代码中的某处执行许多内存操作。
答案 3 :(得分: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];
}
您必须向自动释放池中的对象发送自动释放消息。当发布消息发送到池时,它们将被释放。