简体   繁体   中英

NSFetchedResultsControllerDelegate methods not called when UITableView is a subview of UIView (data initially loads)

I have a UIView that contains a UITableView . These are managed by a UIViewController that inherits the delegate methods UITableViewDelegate and NSFetchedResultsControllerDelegate . I am able to populate the table just fine using the NSFetchedResultsController , however the delegate methods (specifically controllerWillChangeContent ) are not called when changes are made to managed objects in the fetchObjects .

I have checked independently that changes are made to the objects, and those changes I have reflected in the cells, however you must manually reload the cells (scrolling up) to see the changes occur. The behavior I am looking for is that when the changes are made to the object (via save), that the NSFetchedResultsControllerDelegate methods fire so I can make the updates to the table view.

Just to be clear, the data is populated from the database when the view loads, so I know the code pulls that just fine.

Header interface

@interface HSAwardsViewController : UIViewController <UITableViewDelegate, UITableViewDataSource, NSFetchedResultsControllerDelegate>

@property (nonatomic, retain) IBOutlet UITableView *tableView;

@property (nonatomic, retain) NSPersistentStoreCoordinator *persistentStoreCoordinator;
@property (nonatomic, retain) NSFetchedResultsController *fetchedResultsController;
@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;

@end

init method - Setting up managedObjectContext (uses Magical Record)

- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];
    if (self) {
        HSInternalDB *dbInstance = [HSInternalDB getInternalDB];
        self.persistentStoreCoordinator = [dbInstance getPersistentStoreCoordinator];
        self.managedObjectContext = [NSManagedObjectContext MR_contextWithStoreCoordinator:self.persistentStoreCoordinator];

        self.tableView.delegate = self;
        self.tableView.dataSource = self;

        NSError *error;
        if (![[self fetchedResultsController] performFetch:&error]) {
            // Update to handle the error appropriately.
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            exit(-1);  // Fail
        }
    }
    return self;
}

Setting up the NSFetchedResultsController and assigning the delegate

- (NSFetchedResultsController *)fetchedResultsController {

    if (_fetchedResultsController != nil) {
        return _fetchedResultsController;
    }

    NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Award"];

    NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"gameTypeIdentifier" ascending:NO];

    [fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];
    [fetchRequest setFetchBatchSize:20];

    NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil];

    NSError *error = nil;
    [theFetchedResultsController performFetch:&error];
    theFetchedResultsController.delegate = self;
    self.fetchedResultsController = theFetchedResultsController;

    // Listen for this notification so that the managedObjectContext runs on the main thread
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contextChanged:) name:NSManagedObjectContextDidSaveNotification object:nil];

    return _fetchedResultsController;
}



- (void)contextChanged:(NSNotification*)notification
{
    NSManagedObjectContext *context = [notification object];
    if ([context isEqual:self.managedObjectContext]) {
        return;
    }

    if (![NSThread isMainThread]) {
        [self performSelectorOnMainThread:@selector(contextChanged:) withObject:notification waitUntilDone:YES];
        return;
    }

    [[self managedObjectContext] mergeChangesFromContextDidSaveNotification:notification];
}

As far as I can see, all the connections are are made in code or in the storyboard. I know a change is recorded in my database because I am listening for the NSManagedObjectContextDidSaveNotification .

This has me stumped, so I appreciate any suggestions or bread crumbs. I'm happy to answer any questions or post more code if needed!

contextChanged:应该在MainThread上调用,因为它涉及UI更新。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM