Reputation: 49087
Is it worth storing references to other viewcontrollers that the current viewcontroller opens? If I have one viewcontroller displaying a screen with a button that opens a popoverviewcontroller, should I then keep a reference to it and then check afterwards to see if the variable is nil to only make the popoverviewcontroller once? Or is it unnecessary? It lead to many extra variables in some cases, and additional code, but it would be great if someone could say if this is unnecessary or not.
if (self.popoverVC == nil) {
UIPopoverController *popVC = [[UIPopoverController alloc] initWithContentViewController:self.configureTest];
popVC.popoverContentSize = CGSizeMake(320.0, 460.0);
popVC.delegate = self;
self.popoverVC = popVC;
[popVC release];
}
Upvotes: 1
Views: 138
Reputation: 90117
The reason for keeping a reference to UIPopoverController (btw it's not a subclass of UIViewController, it's a subclass of NSObject) is a slightly different one than for keeping a reference to a UIViewController.
When you present a UIPopoverController it is not automatically retained. So you have to retain it yourself. Compared to UIViewController that are automatically retained when you present (or push) them.
There were tricks that just retained the controller without keeping a reference and released it in the delegate method that informed you that the popover was dismissed.
For me, those tricks felt always a little bit dirty. For example you didn't have the option to manually dismiss the popover.
Since ARC is publicly documented on the LLVM page I can tell you that those tricks stop to work if you use ARC. You have to keep a reference otherwise the compiler will release it immediately after you have left the method that presents the popover.
Upvotes: 1
Reputation: 69027
Storing references to other controllers is fine with me and I do it whenever it seems reasonable to me. Think of the delegate pattern as a way to model the interaction between your controllers.
There are alternatives, though.
In you specific case, instead of storing the reference to the controller, you could set a flag (but I don't know if this makes sense for your specific workflow) specifying that the button was pressed.
Not applicable in your case but possibly useful in general is accessing the "parent" hierarchy of UIViewController
s. This is not explicitly maintained by UIKit, so either you set the parentViewController
property or you can go from one controller to its parent navigating the UIResponder
hierarchy. This is not applicable to your case, it seems to me, because communication would be initiated by the child controller (in your case you are interested in the opposite). Anyway, google for it, if you are interested.
Another option you have is using notifications: one controller can register for notifications, another can observe it.
[[NSNotificationCenter defaultCenter] postNotificationName:@"notifName" object:self];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reactToNotif:) name:@"notifName" object:nil];
This is a bit more expensive than a function call, but it requires no ivar and no coupling between controllers.
Upvotes: 3
Reputation: 358
That's perfectly sensible, especially if you want popVC to maintain its state between appearances. It would be wise to release inactive vc's when you get a memory warning.
Upvotes: 2