Delegating is a good programming practice for many situations but that doesn't mean you have to use it if you're not comfortable with it. Both delegating and notifications help decouple the view controllers from each other, which is a good thing. Notifications might be a little easier to code and offer the advantage that multiple objects can observe one notification. With delegates, such a thing cannot be done without modifying the delegating object (and is unusual).
Some advantages of delegating:
- The connection between delegating object and delegate is made clearer, especially if implementing the delegate is mandatory.
- If more than one type of message has to be passed from delegatee to delegate, delegating can make this clearer by specifying one delegate method per message.
For notifications, you can use multiple notification names but all notifications end up in the same method on the side of the observer (possibly requiring a nasty switch statement).
Only you can decide what pattern is more appropriate for you. In any case, you should consider not having your view controller send the notification or the delegate message. In many cases, the view controller should change the model and then the model should inform its observers or its delegate that it has been changed.
Implementing a delegate pattern is simple:
In your ChildViewController.h, declare the delegate protocol that the delegate must implement later:
@protocol ChildViewControllerDelegate <NSObject>
@optional
- (void)viewControllerDidChange:(ChildViewController *)controller;
@end
At the top of the file, create an instance variable to hold the pointer to the delegate in your ChildViewController:
@protocol ChildViewControllerDelegate;
@interface ChildViewController : UIViewController {
id <ChildViewControllerDelegate> delegate;
...
}
@property (assign) id <ChildViewControllerDelegate> delegate;
...
@end
In RootViewController.h, make your class conform to the delegate protocol:
@interface RootViewController : UIViewController <ChildViewControllerDelegate> {
...
In the RootViewController implementation, implement the delegate method. Also, when you create the ChildViewController instance, you have to assign the delegate.
@implement RootViewController
...
// in some method:
ChildViewController *controller = [[ChildViewController alloc] initWithNibName:...
controller.delegate = self;
...
- (void)viewControllerDidChange:(ChildViewController *)controller {
NSLog(@"Delegate method was called.");
}
...
In the ChildViewController implementation, call the delegate method at the appropriate time:
@implementation ChildViewController
...
// in some method:
if ([self.delegate respondsToSelector:@selector(viewControllerDidChange:)]) {
[self.delegate viewControllerDidChange:self];
}
...
That's it. (Note: I have written this from memory so there are probably some typos/bugs in it.)
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…