First off, it would be advisable to check if the popover is being presented, this will conveniently also check if it is allocated:
if ([self.popover isPopoverVisible]) {
[self.popover dismissPopoverAnimated:NO];
}
Now, the issue is, you don't get the delegate callback - (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController
if you dismiss the popover programmatically like this, but you need a strong reference to the popover until it is no longer visible.
The way to do this is delay setting the property to nil until you return to the main run loop, as when you get back to the main run loop, all animations will have finished and thus the popover will no longer be visible.
You will want to move the code setting the popover to nil into another method:
- (void)releasePopover {
self.popover.delegate = nil;
self.popover = nil;
}
Then, in your rotation callback, add this method to fire on the main run loop, I like to do this by adding an invocation operation to the main run loop:
if ([self.popover isPopoverVisible]){
[self.popover dismissPopoverAnimated:NO];
NSInvocationOperation *invocationOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(releasePopover) object:nil];
[[NSOperationQueue mainQueue] addOperation:invocationOperation];
}
Finally, for the sake of cleanliness, you will probably want to call -releasePopover
from inside your - (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController
callback.
So, putting it all together:
- (void)releasePopover
{
self.popover.delegate = nil;
self.popover = nil;
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
if ([self.popover isPopoverVisible]){
[self.popover dismissPopoverAnimated:NO];
NSInvocationOperation *invocationOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(releasePopover) object:nil];
[[NSOperationQueue mainQueue] addOperation:invocationOperation];
}
}
- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController
{
[self releasePopover];
}
Having said all that, unless there is a good reason, you may just want to keep the popover around to reuse and only set it to nil when you get low-memory warnings and/or if your view is unloaded, as Chris Loonam's answer mentioned