Objective-C,正确释放一个对象

时间:2013-03-23 19:04:02

标签: ios objective-c memory-management

我在标题文件中定义了一个对象:

@property (nonatomic, retain) UIBarButtonItem *printButton;

实施文件中:

@synthesize printButton;

self.printButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self action:@selector(printWebPage:)];
[self.view addSubview:printButton];
[printButton release]; // Should I release it here?

- (void)dealloc
{
  [printButton release];
  [super dealloc];
}

我的问题是,在release/autorelease之后我是否总是 addSubview个对象(声明为保留属性),并且还将其释放dealloc即使我将在其他功能中使用它?!

3 个答案:

答案 0 :(得分:3)

propertyretain时,它会保留新值并将release消息发送到旧值。此外,您必须release中的dealloc此属性。

正确的方法是:

self.printButton = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self action:@selector(printWebPage:)] autorelease];

同样self.view addSubView保留subView,超级视图负责释放它。

答案 1 :(得分:2)

当您不再需要它们时,您应该释放您的对象(如果不使用ARC)。在你的情况下,一旦添加了视图,你就不再需要它的引用(除非你打算在你的类中使用它,在这种情况下不要释放它)。

正如@AndrewMadsen在评论中提到的那样,您发布了一个您拥有引用的对象(通过使用newcopymutableCopy明确保留或获取引用,或alloc方法)。

您可以找到更多信息here

答案 2 :(得分:2)

为了保持周围,物体需要至少保留一次。不止一次是可以接受的,但关键是至少一次。保留,你说:'我需要这个',并且通过发布,你说'我不再需要它'。在你被解除分配之后,保留比你需要更长的东西是很粗鲁和浪费的。这样做是一次泄密。

针对您的具体问题:如果您的财产被保留,那么您必须在某个时候释放。在您的dealloc是一个好的时间,或者在您拥有的东西再次保留之后是一个更好的时间。向子视图添加视图是将对象添加到保留的数组(您的UIView超类保留一组子视图)。数组本身保留了它的元素。因此,在您添加后,版本就会很好。

此外,由于您知道您的子视图阵列并且其内容将在您的生命周期内保留,因此根本不保留您的副本更加清晰。这就是为什么子视图出口通常被宣布为弱的原因。所以我会做以下事情:

@property(nonatomic, weak) UIBarButtonItem *printButton;

然后在init:

UIBarButtonItem *aPrintButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self action:@selector(printWebPage:)];
// this is just a stack variable, retained because of the alloc
[self.view addSubview:aPrintButton];  // this provides a second retain
self.printButton = aPrintButton;      // this does not retain because it's setter is declared weak
[aPrintButton release]; // release here subtracts one retain, leaving the one you need

您的子类不再需要更明确的版本,因为UIView将负责释放它的子视图数组,NSArray将负责释放它的元素。