目标c -如何正确管理id实例变量的分配和保留



我有一个类,它有一个属性:

@property (nonatomic, assign) id customDatePicker

根据用户的选择,我将需要一个UIDatePicker或一个UIPicker,所以我对ivar进行类型转换并保留它,然后将其dealloc。这是正确的方式来管理属性的内存吗?

// 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];
}

No。

当您将属性声明为assign时,您不应该保留该对象。assign选项用于非对象变量,以及具有retain ed属性将创建循环的情况,两个对象相互保留。将属性声明为assign意味着您将不管理对象的内存;你既不能调用retain也不能调用release

您还过度保留了选择器对象。保留一个对象创建对该对象的权利要求;你不想让它消失,直到你说你结束了它。通过调用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内存管理文档

最新更新