Reputation: 29458
I have an ivar that is a UIPopoverController. When it gets dismissed, I want to clean up memory. I call the following method when the popover gets dismissed, or if the user pressed the BarButtonItem when the popover is already being presented to the user.
- (void)popoverCleanup:(UIPopoverController *)popoverController {
popoverController.delegate = nil;
popoverController = nil;
}
I set a breakpoint and tried following the code and looking at the memory. I see that my ivar Popover and the method parameter popoverController both point to the same memory address. When I hit the first line, I see the delegate set to nil on both the Popover and popoverController parameter. When I reach the end of the method however, I see only popoverController's memory set to nil, whereas the ivar Popover does not get set to nil. Is there a reason for this?
Thanks.
Upvotes: 0
Views: 328
Reputation: 47729
It should be noted that setting an instance variable to nil does not release the object pointed to.
If you want to release the object, the simplest thing is to have it managed as a property and set the property to nil.
Bear in mind that popoverController = nil;
is not the same as self.popoverController = nil;
. The former is setting the INSTANCE VARIABLE to nil. The latter is setting the PROPERTY to nil, and if the property is defined with "retain", the the addressed object will be released.
Upvotes: 1
Reputation: 13694
This is because popoverController and your instance variable are not the same variable even though they point to the same thing (same pointer instance before you set it to nil).
In that method (- (void)popoverCleanup:(UIPopoverController *)popoverController
) you need to set your instance variable to nil rather than popoverController variable. Also if you are not already, you'd need to release your popover and it should set the instance variable to nil if there is nothing else retaining it
Upvotes: 2
Reputation: 26683
By doing this, you are just saying you don't want to hold a popoverController pointer, no matter to what it points. Nothing get's released here. Proper way to release a popover is implementing it's delegate method for dismissing and release it there.
- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController {
[popoverController release];
}
Keep in mind that setting an ivar to nil doesn't release the object that ivar was pointing to, it usually leaks it. You can only do that with copied or retained properties because they work so that the retain or copy the new value (nil, which does nothing when retained or copied as it's not really an object) and release the old one. You should only set the ivar to nil after releasing it so that if you accidentally send it a message later, you don't crash for accessing released memory.
Edit: also keep in mind that there is really no need for ivar if you only want to present a popover and release it. Just create a local variable and present a popover. Once delegate method gets called it will have a pointer to the popover object, no need to keep ivar just for that. Only case where you would need an ivar for popover is if you wanted to create it and present it multiple times, then release it when done with it forever, like when leaving view controller from which you presented it.
Upvotes: 2