The correct way is for your subcontroller to ask the main controller to remove it. If you want to reduce the coupling between the two controllers, create a delegate protocol for your subcontroller:
// This forward declaration avoids having a circular dependency
// between MySubcontroller and MySubcontrollerDelegate
@class MySubcontroller;
@protocol MySubcontrollerDelegate
- (void)hideMySubcontroller:(MySubcontroller*)subcontroller;
@end
If there is other information that the subcontroller needs to communicate to the supercontroller, this is a great place to add relevant calls. You might not need to do so right away, but keep it in mind for future versions of your app.
Then add a delegate
property to the subcontroller:
@interface MySubcontroller : UIViewController {
id <MySubcontrollerDelegate> delegate;
...
}
@property (assign) id <MySubcontrollerDelegate> delegate;
...
@end
Instead of calling removeFromSuperview
on its view, the subcontroller should call hideMySubcontroller:
on its delegate, passing self
as the argument.
Your main controller should then declare that it implements the delegate protocol:
@interface MyMainController : UIViewController <MySubcontrollerDelegate>
...
@end
When the main controller creates a subcontroller, it should set the subcontroller's delegate
property to self
. It should implement a hideMySubcontroller:
method which removes the subcontroller's view, deallocates the subcontroller, and does whatever else is needed.
Using a delegate protocol means that the subcontroller doesn't have to have any knowledge of what kind of object will use it; it just knows that there is such an object somewhere and that it will conform to the delegate protocol. Thus, the coupling between the two controllers is kept as small as possible.
By the way, if you can manage it, it's actually better to keep the subcontroller around in case you need to use it again; that'll save the processing time it would take to recreate it. (However, you should release it if you receive a memory warning.)