Understanding @property memory management
Hey, I'm just trying to get things 100% clear in my head in regards to memory management on the iPhone, i'm pretty sure i have a good understanding, although i'm not 100% confident.
Let's create an example property that is a NSArray:
@interface ExampleAppDelegate : NSObject {
NSArray *myArray;
}
@property (nonatomic,retain) NSArray *myArray;
And then synthesize the property so that we can use getters and setters:
@synthesize myArray;
Now here is where i get slightly confused.. say we create an array in an external class and assign it to our delegates myArray:
appDelegate = (ExampleAppDelegate *)[[UIApplication sharedApplication] delegate];
NSArray *exampleArray = [[NSArray alloc] init];
appDelegate.myArray = exampleArray;
[exampleArray release];
Now we have assigned myArray with a retain count of one as it has taken the allocated exampleArray, because of this we will be required to call release inside the delegates dealloc so that myArray is not leaked when the delegate is destroyed:
-(void)dealloc {
[super dealloc];
[myArray release];
}
Although if i was to assign myArray like so:
appDelegate = (ExampleAppDelegate *)[[UIApplication sharedApplication] delegate];
NSArray *exampleArray = [NSArray arrayWithObject:[NSString stringWithFormat:@"Hello world"]];
appDelegate.myArray = exampleArray;
Then i am not required to call [myArray release];
in the dealloc because the memory management is handled for me and doing so will over release the object assigned to开发者_高级运维 myArray?
You still have to release myArray. I don't see any difference in behaviour of retaining between your first assignment and the second one, only the creation of exampleArray changed.
In the first assignment you did create a not autoreleased instance which had a retain count of 2 after you have assigned it to your property. After that step you released once, so retain count dropped to one of that instance.
The second assignment lead to a retain count of 2, which drops to 1 automatically, after the next run loop cycle of the app, 'cause NSArray arrayWithObject does return an autoreleased instance, which you have to retain yourself, if you like to use it in future.
You have to release myArray
in both cases. myArray
is "owned" by your class, therefore it is responsible for decreasing the reference count if myArray
is no longer needed. It does not matter how the array being assigned to myArray
was allocated; whenever you do the assignment, the synthesized setter function will increase the retain count of the array (since you specified it that way), therefore your class owns a reference to the array and you have to compensate for it in the destructor.
The same would apply if you had used (nonatomic, copy)
-- in this case, your class makes a copy of the array being assigned, therefore it also owns the copy.
Had you used (nonatomic, assign)
, you would not own myArray
, but in this case you can never be sure that the array is still around when you are trying to use it - it may have happened that some other part of your program has already released the array and it was deallocated in the meanwhile. Therefore, for Objective C objects, you should never use assign
in the property specification except for the case of properties having a plain old C type (such as NSInteger
, which is just a typedef to one of the integer data types in C).
精彩评论