I've tried to set up a very basic delegate between a TableViewController
and a DetailViewController
, but the methods are never called. Here's my code:
DetailViewController.h
@protocol DetailViewControllerDelegate
- (void) detailViewControllerDidLike;
- (void) detailViewControllerDidUnlike;
- (void) detailViewControllerDidDislike;
@end
DetailViewController.m
- (IBAction) changeLikedSwitch: (id) sender
{
UISwitch *likedSwitch = (UISwitch *) sender;
if ([likedSwitch isOn]) {
[_selectedQuote setIsLiked: [NSNumber numberWithBool: YES]];
[self.delegate detailViewControllerDidLike];
} else {
[_selectedQuote setIsLiked: [NSNumber numberWithBool: NO]];
[self.delegate detailViewControllerDidUnlike];
}
NSError *error;
if (![[[CDManager sharedManager] managedObjectContext] save:&error]) NSLog(@"Saving changes failed: %@, %@", error, [error userInfo]);
}
- (IBAction) changeDislikedSwitch: (id) sender
{
UISwitch *dislikedSwitch = (UISwitch *) sender;
if ([dislikedSwitch isOn]) {
[_selectedQuote setIsDisliked: [NSNumber numberWithBool: YES]];
[self.delegate detailViewControllerDidDislike];
[self dismissViewControllerAnimated: YES completion: nil];
} else {
[_selectedQuote setIsDisliked: [NSNumber numberWithBool: NO]];
}
NSError *error;
if (![[[CDManager sharedManager] managedObjectContext] save:&error]) NSLog(@"Saving changes failed: %@, %@", error, [error userInfo]);
}
TableViewController.h Interface line:
@interface TableViewController : UITableViewController <NSFetchedResultsControllerDelegate, DetailViewControllerDelegate>
TableViewController.m
- (void) detailViewControllerDidLike
{
NSLog(@"detailViewControllerDidLike!");
[self.tableView reloadData];
}
- (void) detailViewControllerDidUnlike
{
NSLog(@"detailViewControllerDidUnlike!");
[self.tableView reloadData];
}
- (void) detailViewControllerDidDislike
{
NSLog(@"detailViewControllerDidDislike!");
[self.tableView reloadData];
}
None of these methods are called. I'm trying to work out whether it's because I haven't set the delegate, but I don't understand how I can do that. There isn't an instance of my DetailViewController
in my TableViewController
, so how am I supposed to set one of its properties? Isn't the whole point of having a delegate that I don't need to create a concrete link between the classes? Very, very confused here.
You do need to set the delegate, for delegate methods to be called.
You must have a class that creates both the TableViewController and the DetailViewController? when they are created you would call
[myDetailViewControllerObject setDelegate:myTableViewControllerObject];
to set the delegate. This is assuming you've defined a delegate property in DetailViewController with
@property (readwrite, weak) id<DetailViewcontrollerDelegate> delegate;
A further explanation of delegates:
The point of a delegate is so that you don't need a specific type of object, you only need an object that implements the protocol. There still needs to be a connection between the delegate and the "delegator". If you want no concrete connection, then you would want to use an NSNotification, which is very much a "shout into the ether, and hope something is listening" method of communication.
In this case, a delegate is the correct thing to use. Delegates should be for one-to-one relationships, NSNotification are best used for one-to-N type relationships, where N can be 0 or more.