0

I'm working on an app that has a shopping cart. When I add a product in my shopping cart, my button segues to a table view controller modally. Then when I select a row, the modal view controller should be dismissed. I tried to implement this using my delegate. Here's my code:

(irrelevant code omitted)

ItemsTableViewController (the list of products to choose from)

//the header file
@class ItemsTableViewController;

@protocol ItemsTableViewControllerDelegate <NSObject>

- (void) itemsTableViewController: (ItemsTableViewController *)sender
                 didSelectProduct: (Product *) aProduct;

@end

@interface ItemsTableViewController : CoreDataTableViewController

@property (nonatomic, strong) UIManagedDocument *itemDatabase;

@property (nonatomic, weak) id <ItemsTableViewControllerDelegate> delegate;

@end

//snippets from the implementation

- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    Product *item = [self.fetchedResultsController objectAtIndexPath:indexPath];

    [self.delegate itemsTableViewController:self didSelectProduct:item];
    NSLog(@"DID SELECT ROW AT index %d with name %@", indexPath.row, item.name);

}

//here's my shopping cart, the ItemsTableViewController delegate

- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
    if ([segue.identifier isEqualToString:@"Show Products List"]){
        ItemsTableViewController *itemsTVC = (ItemsTableViewController *)segue.destinationViewController;
        itemsTVC.delegate = self;

    }
}
- (void) itemsTableViewController:(ItemsTableViewController *)sender didSelectProduct:(Product *)aProduct{
    //adds the product in the shopping cart
    [self.shoppingCart addObject:aProduct];
    [self.products reloadData];
    [self dismissModalViewControllerAnimated:YES];
    NSLog(@"from the delegate got product %@", aProduct.name);
}
acecapades
  • 893
  • 12
  • 23
  • What actually happens when you run it? Where else have you put calls to `NSLog` (or breakpoints) to make sure your variables are assigned properly and your methods are getting called (or not called)? What is the output from your logging? – rob mayoff Feb 17 '12 at 06:22
  • It logs that a row was selected and the item is identified but from the delegate's part it doesn't log NSLog(@"from the delegate got product %@", aProduct.name); – acecapades Feb 17 '12 at 06:23
  • is there a reason your delegate is weak? – Rok Jarc Feb 17 '12 at 13:02
  • all delegates are supposed to be weak @rokjarc – acecapades Feb 19 '12 at 09:28
  • shouldn't it be __unsafe_unretained for use with ARC? ie: http://stackoverflow.com/questions/7753841/recommended-way-to-declare-delegate-properties-with-arc – Rok Jarc Feb 19 '12 at 11:17

1 Answers1

1

The destination of your segue is a UINavigationController, not an ItemsTableViewController. Perhaps you put your ItemsTableViewController inside a UINavigationController on your storyboard. Try this:

UINavigationController *navController = segue.destinationViewController;
ItemsTableViewController *itemsTVC = (ItemsTableViewController *)navController.topViewController;
itemsTVC.delegate = self;
rob mayoff
  • 375,296
  • 67
  • 796
  • 848
  • If setting the delegate to strong didn't fix it, then something else is going on. Either `tableView:didSelectRowAtIndexPath:` is being sent to a different instance of `ItemsTableViewController` than the instance you accessed in `prepareForSegue:sender:`, or something is setting the delegate to nil after you set it in `prepareForSegue:sender:`. – rob mayoff Feb 17 '12 at 06:54
  • how can I check whether tableView:didSelectRowAtIndexPath: is sent to the right instance? – acecapades Feb 17 '12 at 08:22
  • but I set the destinationViewController like this:ItemsTableViewController *itemsTVC = (ItemsTableViewController *)segue.destinationViewController; itemsTVC.delegate = self; So I think tableView: didSelectRowAtIndexPath: is being sent to that instnce. How will I check what's setting it nil then? – acecapades Feb 17 '12 at 08:23
  • You can log `itemsTVC` with the `%p` format, and then log `self` with `%p` in `tableView:didSelectRowAtIndexPath:`, and make sure you see the same value. – rob mayoff Feb 17 '12 at 08:32
  • You could try setting a breakpoint on `-[ItemsTableViewController setDelegate:]`. – rob mayoff Feb 17 '12 at 08:34
  • You could try using a watchpoint. Put a breakpoint in `-[ItemsTableViewController setDelegate:]`. Then get the address of the delegate variable with `p/x &self->delegate` or `p/x &self->_delegate` (depending on how you named the instance variable). It will be something like `0x1030618e0`. Then you can set a watchpoint with a command like `watch *(id *)0x1030618e0`. – rob mayoff Feb 17 '12 at 08:37
  • ok I'll try you're suggestions first. btw, I just realized that I'm inside a tab bar controller. That's my presentingViewController's class when my itemTVC is up modally. – acecapades Feb 17 '12 at 08:42
  • I got different values for self and itemsTVC --> itemsTVC: 0x8113710, self: 0x81134c0 – acecapades Feb 17 '12 at 08:48
  • What's the output if you use `%@` instead of `%p`? – rob mayoff Feb 17 '12 at 09:03
  • here's the output using %@: itemsTVC: , self: – acecapades Feb 19 '12 at 09:27
  • seems like itemsTVC is not being casted as an ItemsTableViewController because I also NSLog-ed what segue.destinationViewController is and this is what I got: destinationVC: – acecapades Feb 19 '12 at 09:44