如何正确管理id实例变量assign然后保留

时间:2011-07-08 17:40:20

标签: objective-c

我有一个具有属性的类:

@property (nonatomic, assign) id customDatePicker

根据用户的选择,我需要一个UIDatePicker或一个UIPicker,所以我对ivar进行类型转换并保留它,然后将其解除分配。这是管理财产记忆的正确方法吗?

// init snippet
if (useUIDatePicker) {
  customDatePicker = (UIDatePicker *)[[[UIDatePicker alloc] initWithFrame:frame] retain];
} else {
  customDatePicker = (UIPickerView *)[[[UIPickerView alloc] initWithFrame:frame] retain];
}

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

1 个答案:

答案 0 :(得分:2)

没有。

当您将属性声明为assign时,您不应该保留该对象。 assign选项用于非对象变量,并且对于具有retain ed属性的情况将创建一个循环,两个对象互相保留。将属性声明为assign意味着您不会管理对象的内存;你不应该打电话给retainrelease

您也过度保留了选择器对象。保留对象会在对象上创建声明;你不要让它消失,直到你说你已经完成它。您通过调用release放弃声明,允许删除对象。当您致电alloc时,会产生与呼叫retain相同的声明。所以这一行:

[[[UIDatePicker alloc] initWithFrame:frame] retain];

创建两个声明,一个用于alloc,另一个用于retain。之后,您只需拨打release一次,这意味着您将始终对此对象提出一项声明,并且它将变为内存泄漏。

你应该做的是:

@property (nonatomic, retain) id customDatePicker


if (useUIDatePicker) {
    customDatePicker = [[UIDatePicker alloc] initWithFrame:frame];
} else {
    customDatePicker = [[UIPickerView alloc] initWithFrame:frame];
}

现在,由于您使用了alloc,因此您对选择器只有一项声明。

(您不需要转换赋值;当您分配给通用指针时,您可以使用任何类型的对象。)

另请参阅Apple Memory Management文档。