我有一个类,它有一个属性:
@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内存管理文档