我遇到了一个似乎在自动释放池中被称为“溺水”的问题。
我的代码正确创建和销毁对象。但是,我使用了一些类方法,在我不知道的情况下自动释放几个变量。考虑到它们每分钟循环成千上万次......我发现自己淹没在程序中某处遗失的数千个未发布的物体中。
2个问题:
所以要么我不使用AT ALL的类方法 - 这是一个永久的解决方案,或者,即便如此,某些实例方法(Foundation,UIKit)仍然会在不知情的情况下自动释放对象吗?
或者我可以在调用类方法之前分配一个自动释放池,并在调用类方法之后将其耗尽 - 这是一个永久的解决方案吗?
答案 0 :(得分:2)
仅仅因为你不使用类方法并不意味着你要避免使用自动释放的对象。例如:NSString * path = [anotherString stringByAppendingPathComponent:@"foo"]
返回一个自动释放的对象,但不涉及任何类方法。据我所知,避免自动释放对象的唯一方法是不使用对象。如果确实想要走这条路线,请查看CoreFoundation。 (我不建议走那条路。)
如果您确实有一些疯狂的工厂方法可以创建大量的自动释放池,那么我可能会这样做:
+ (id) crazyFactoryMethodWithFoo:(id)foo { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; id returnValue = nil; //generate gobs of autoreleased objects returnValue = [something retain]; [pool release]; return [returnValue autorelease]; }
通过在排空池之前显式保留返回值,可以确保返回值超出自动释放池的销毁范围。然后通过自动释放返回值并返回它来平衡retain
。
答案 1 :(得分:2)
Dave DeLong已经回答了你的问题,但通常只有当你把游泳池填得太高时才是你的问题。在这种情况下,只需为循环的每次迭代创建另一个自动释放池。
for (NSUInteger i = 0; i < 1000000000; i++)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// do the work
[pool release];
}
对象会自动添加到当前线程的最近创建的自动释放池中。通过为循环的每次迭代创建一个,您可以快速摆脱不需要的对象,而不是让它们堆积在运行循环池中。