Jim
Jim

Reputation: 5960

UITableViewController viewWillAppear

I have a view controller that is a subclass of UITableViewController. Here is my viewWillAppear:animated method:

- (void)viewWillAppear:(BOOL)animated
{  
    [super viewWillAppear:animated]; 

    if (fetchedResultsController != nil) {
        [fetchedResultsController release];
        fetchedResultsController = nil;
    }

    [self.fetchedResultsController performFetch:nil];
    [self.tableView reloadData];
}

I am getting confused by seeing the fetchedResultsController being accessed when [super viewWillAppear:animated] is called. Since super is a UITableViewController, and there is no viewWillAppear:animated method for that class, per se, then its superclass viewWillAppear:animated should be called, right? If that's correct, then the UIViewController class should not be accessing UITableViewController delegate methods. But I see that numberOfSectionsInTableView is getting called. I'm not sure why the call to super viewWillAppear:animated would do this.

So before I explicitly run the peformFetch and reloadData, the table is getting populated. At that time, the data it is being populated with is out of date.

Here is the fetchedResultsController code

- (NSFetchedResultsController *) fetchedResultsController {
    if (fetchedResultsController != nil) {
        return fetchedResultsController;
    }

    NSFetchRequest *fetchRequest = ...
    NSEntityDescription * entity = ...

    [fetchRequest setEntity:entity];

    [fetchRequest setFetchBatchSize:10];

    NSSortDescriptor *aSortDescriptor = ...
    NSSortDescriptor *bSortDescriptor = ...

    NSArray *sortDescriptors = ...
    [fetchRequest setSortDescriptors:sortDescriptors];

    NSFetchedResultsController *aFetchedResultsController = ...

    aFetchedResultsController.delegate = self;

    self.fetchedResultsController = aFetchedResultsController;

    [aFetchedResultsController release];
    [fetchRequest release];
    ...        
    [sortDescriptors release];

    NSError *error = nil;

    if (![fetchedResultsController performFetch:&error]) {
        NSLog(@"Unresolved Error %@, %@", error, [error userInfo]);
        abort();
    } 

    return fetchedResultsController;

}

Upvotes: 1

Views: 2019

Answers (1)

Jim
Jim

Reputation: 73966

The documentation specifically describes this behaviour:

When the table view is about to appear the first time it’s loaded, the table-view controller reloads the table view’s data. It also clears its selection (with or without animation, depending on the request) every time the table view is displayed. The UITableViewController class implements this in the superclass method viewWillAppear:. You can disable this behavior by changing the value in the clearsSelectionOnViewWillAppear property.

Upvotes: 1

Related Questions