之后自动释放或释放更好吗?

时间:2009-08-16 02:05:35

标签: iphone memory-management uikit

在很多情况下,人们会分配一个实例,并在将其分配给其他内容后立即释放它,并在内部保留它。

例如,

UIView *view = [[UIView alloc] initWithFrame...];
[self addSubView:view];
[view release];

我听说有人建议我们自动释放而不是立即释放。

所以上面变成了:

UIView *view = [[[UIView alloc] initWithFrame...] autorelease];
[self addSubView:view];

这里的最佳做法是什么?优点和缺点?

3 个答案:

答案 0 :(得分:14)

在大多数情况下,无论哪种方式都无关紧要。由于-autorelease只是意味着对象将在运行循环的当前迭代结束时释放,因此对象将以任一方式释放。

使用-autorelease的最大好处是您不必担心方法上下文中对象的生命周期。因此,如果您稍后决定要在对象上次使用后对某些对象执行某些操作,则无需担心将调用移至-release

使用-release时的主要实例与使用-autorelease相比会产生显着差异,如果您在方法中创建了很多的临时对象。例如,请考虑以下方法:

- (void)someMethod {
    NSUInteger i = 0;
    while (i < 100000) {
        id tempObject = [[[SomeClass alloc] init] autorelease];

        // Do something with tempObject

       i++;
    }
}

当此方法结束时,您将有100,000个对象位于自动释放池中等待释放。根据{{​​1}}的类别,这可能是也可能不是桌面上的主要问题,但它肯定会出现在内存受限的iPhone上。因此,如果要分配许多临时对象,则应该使用tempObject而不是-release。但是,对于许多/大多数用途,你不会发现两者之间存在任何重大差异。

答案 1 :(得分:5)

我同意Matt Ball。我要补充一点,如果你经常发现自己使用这种模式,那么编写一个快速类别可能很方便:

@interface UIView (MyCategories)
- (UIView *)addNewSubviewOfType:(Class)viewType inFrame:(NSRect)frame;
@end

@implementation UIView (MyCategories)
- (UIView *)addNewSubviewOfType:(Class)viewType inFrame:(NSRect)frame
{
    UIView * newView = [[viewType alloc] initWithFrame:frame];
    [self addSubView:newView];
    return [newView autorelease];
}
@end

可以使用如下:

UIView * view = [someView addNewSubviewOfType:[UIView class]
                                      inFrame:someFrame];

它甚至适用于其他类型,只要它们来自UIView:

UIButton * button = [mainView addNewSubviewOfType:[UIButton class]
                                          inFrame:buttonFrame];

答案 2 :(得分:4)

我通常会尽可能地去发布而不是-autorelease。这源于多年调试和增强其他人的Objective-C代码的经验。在任何地方使用自动释放的代码使得在对象被过度释放时更难调试,因为额外的释放发生在远离错误代码的地方。

当他们不了解可可内存管理如何工作时,许多人也使用自动释放。学习规则,学习API,您几乎不需要自动释放对象。

最后一个小问题是,如果您不需要自动释放行为,那么使用自动释放只会不必要地为您的程序添加额外的工作。

相关问题