何时是释放物体的适当时间?

时间:2011-01-29 19:02:52

标签: iphone objective-c xcode release

我仍然对此感到困惑。

我正在Xcode中以编程方式创建一个对象,比如一个UILabel,它也将是一个类范围的属性。

何时是释放对象的适当时间,在创建对象的方法中,还是在正常IBOutlet对象的dealloc方法中?

感谢。

2 个答案:

答案 0 :(得分:3)

这取决于您的属性是否设置为保留值。通常,当属性设置为新值时,您希望访问器(由@synthesize生成)处理保留/释放。你指定这样的属性:

<强> MyController.h

@interface MyController : UIViewController {
 UILabel *myLabel;
}

@property (nonatomic, retain) UILabel *myLabel;

@end

然后,您可以使用@synthesize生成默认的getter和setter。 'retain'属性的默认设置器将释放当前值并保留新值。但是,在dealloc中没有为你做任何事情。这意味着,当控制器被销毁时,您对标签的引用将会泄漏,因为不会调用release。因此,您需要在dealloc中的所有“保留”属性上调用release,如下所示:

<强> MyController.m

@implementation MyController

@synthesize myLabel;

-(void) dealloc {
 self.myLabel = nil;

 [super dealloc];
}

@end

请注意,在这种情况下,self.myLabel = nil几乎等同于调用[myLabel release],因为setter将在现有值上调用release,然后在新值上调用retain。由于新值为nil,因此调用[nil retain]无效。我更喜欢nil而不是释放,因为你也将ivar设置为nil并避免悬空指针。

当您以编程方式创建此类属性而不是Interface Builder时,您无需使用IBOutlet标记它。在使用IB创建控件的情况下,您应该在viewDidUnload中忽略所有IBOutlet引用。这是因为如果未保留控件,则可以将视图与视图一起取消分配。之后引用它会使应用程序崩溃,所以这是一个很好的做法,就像这样:

- (void)viewDidUnload {
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;

    self.myIBLabel = nil;
}

使用属性时发生的另一个常见错误是省略'self'部分。如果您不使用self.myIBLabel表示法,则需要对getter和setter进行双工并直接使用ivar。这不会保留/释放对象。

答案 1 :(得分:2)

你应该在dealloc方法中释放它,虽然这取决于你如何创建你的类属性。

如果你在创建它的方法中释放它,然后在你的类的其他部分使用它(因为你正在使UILabel成为一个类范围的属性,我认为你是),你将当您稍后尝试修改它时,会获得错误的访问权限。请注意,如果您使用的是保留属性,则需要将其考虑在内,在这种情况下,您可以释放标签(因为您已创建标签并将其分配给您的类属性,这将再次保留它)。 / p>

这是一个典型的例子:

- (void) someMethod {
    UILabel *myLabel = [[UILabel alloc] initWithFrame:myFrame];

    self.textLabel = myLabel;
    [myLabel release];
}


- (void) dealloc {
    [textLabel release];
}