当UITableView是UIView的子视图(数据最初加载)时,未调用NSFetchedResultsControllerDelegate方法

时间:2014-03-25 15:09:52

标签: ios objective-c uitableview core-data nsfetchedresultscontroller

我的UIView包含UITableView。它们由UIViewController管理,继承委托方法UITableViewDelegateNSFetchedResultsControllerDelegate。我能够使用NSFetchedResultsController填充表格,但是当对controllerWillChangeContent中的托管对象进行更改时,不会调用委托方法(特别是fetchObjects)。

我已经独立检查了对对象的更改以及我在单元格中反映的那些更改,但是您必须手动重新加载单元格(向上滚动)才能看到更改发生。我正在寻找的行为是,当对对象进行更改(通过保存)时,NSFetchedResultsControllerDelegate方法会触发,因此我可以对表视图进行更新。

为了清楚起见,当视图加载时,数据会从数据库中填充,所以我知道代码可以很好地完成。

标题界面

@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方法 - 设置managedObjectContext(使用魔法记录)

- (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;
}

设置NSFetchedResultsController并指定代理

- (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];
}

据我所知,所有连接都是在代码或故事板中完成的。我知道我的数据库中记录了更改,因为我正在侦听NSManagedObjectContextDidSaveNotification

这让我很难过,所以我感谢任何建议或面包屑。如果需要,我很乐意回答任何问题或发布更多代码!

1 个答案:

答案 0 :(得分:0)

上下文更改:应该在主线程上调用,因为它涉及UI更新。