Jim
Jim

Reputation: 9234

iPhone: UITableView delegate is alive after viewController was released

My ViewController1 pushes ViewController2

ViewController2 *controller =
    [[ViewController2 alloc] init];
[self.navigationController pushViewController:controller
    animated:NO];
[controller release];

ViewController2 has UITableView ... in xib file I connected delegate with File's Owner. Also ViewController2 has Done button

- (IBAction)doneButtonPressed {
     [self.navigationController popViewControllerAnimated:NO];
 }

The problem is that if to click table rows and done button at the same time, sometimes didSelectRowAtIndexPath: method calls after that ViewController2 was popped, and I have SIGABRT error and this thing in logger :

[__NSCFSet tableView:didSelectRowAtIndexPath:]: unrecognized selector sent to instance 0x62579d0'

So how tableView:didSelectRowAtIndexPath can be called after I popped viewController2 ? It should be dead...

Upvotes: 0

Views: 191

Answers (2)

aryaxt
aryaxt

Reputation: 77626

popViewController & pushViewController methods perform their tasks asynchronously. They use an animation block to slide the viewController in and out. The ViewController gets removed from its superview and gets released in the completion portion of the animation block. The crash is because of this delay (I think 0.3 seconds).

Upvotes: 1

Philippe Sabourin
Philippe Sabourin

Reputation: 8075

One easy fix is to do this:

- (IBAction)doneButtonPressed {
     self.tableView.delegate = nil;
     [self.navigationController popViewControllerAnimated:NO];
 }

That way you guarantee that while you're leaving that view no more delegate calls will happen. You could also do this in the dealloc method for the view controller (probably a better place for it).

Upvotes: 2

Related Questions