How to use delegate to pass data backwards/up view controller chain in Obj-C/Cocoa
I know there is plenty on the subject of delegates in the Apple dev docum开发者_JS百科entation, as well as other books I have, and in resources like stackoverflow and others. But I'm still not getting it.
I recently watched the lecture on Navigation View Controllers, etc. in Stanford's CS193P Winter 2010 series, and in that lecture they talk about passing data forward on a stack of view controllers, which is easy. But they made a brief mention that you'd ideally use a delegate/protocol to pass data "backwards" (from detail view controller to list view controller, for example), but they didn't do a demo or post sample code.
I've read and searched for a sample of this exact scenario so I can wrap my head around that use of delegate/protocol, but can't find it. Here's some pseudo-code I'm playing with. Should it achieve passing the data "backwards"?
myListController : UIViewController <SetDataInParent> {
// when pushing detail controller onto stack,
// set DetailController delegate = self
}
myDetailController : UIViewController {
//header file
@protocol SetDataInParent <NSObject>
- (void)willSetValue:(*NSString);
@end
@interface myDetailController {
id <SetDataInParent> delegate;
}
@end
// class/m file
@implementation
@synthesize delegate;
- (void)willSetValue:(*NSString) {
// code here that would take argument
// from detail controller and set
// a value or text field to that
// argument in list controller
}
// send message to list controller class
- [delegate willSetValue:string];
@end
}
A delegate is simply any other Objective-C instance other than the one you are currently to which you will be sending one or more messages. The type you specified (id <SetDataInParent
) reads that it's any Objective-C type that conforms to the SetDataInParent
protocol (which I don't see defined in your code, but you could have it elsewhere.)
When going "backwards" typically the delegate link between the two objects is made at the time the child view is created. Therefore at the point the list view controller creates the detail view controller the former should set the delegate in the latter to self
. The detail view controller then can use that delegate pointer to send messages to the list view controller, either directly via e.g., willSetValue:
or indirectly (via performSelector:withObject:
.) When using performSelector:withObject:
it is generally a good idea to call respondsToSelector:
on the delegate first to make sure you won't throw an exception should the object not respond to that message.
精彩评论