I have a class that has a property:
@pr开发者_JAVA百科operty (nonatomic, assign) id customDatePicker
Based upon user choice I will need a UIDatePicker or a UIPicker so I typecast the ivar and retain it and subsequently dealloc it. Is this the correct way to manage the property's memory?
// 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.
When you declare the property as assign
, you should not be retaining the object. The assign
option is used for non-object variables and for situations where having a retain
ed property would create a cycle, with both objects retaining each other. Declaring a property as assign
means you will not be managing the memory of the object; you should neither call retain
nor release
on it.
You are also over-retaining the picker object. Retaining an object creates a claim on the object; you don't want it to disappear until you say you are done with it. You relinquish a claim, allowing an object to be deleted, by calling release
. When you call alloc
, that creates the same kind of claim as calling retain
. So this line:
[[[UIDatePicker alloc] initWithFrame:frame] retain];
creates two claims, one for alloc
and one for retain
. Later, you only call release
once, which means that you will always still have one claim on this object, and it will have turned into a memory leak.
What you should do is:
@property (nonatomic, retain) id customDatePicker
if (useUIDatePicker) {
customDatePicker = [[UIDatePicker alloc] initWithFrame:frame];
} else {
customDatePicker = [[UIPickerView alloc] initWithFrame:frame];
}
Now you have only one claim on the picker because you used alloc
.
(You don't need to cast the assignment; when you are assign to a generic pointer you can use any kind of object.)
Also take a look at the Apple Memory Management docs.
精彩评论