当 UITableView 是 UIView 的子视图时不调用 NSFetchedResultsControllerDelegate 方法(最初加载数据)
Posted
技术标签:
【中文标题】当 UITableView 是 UIView 的子视图时不调用 NSFetchedResultsControllerDelegate 方法(最初加载数据)【英文标题】:NSFetchedResultsControllerDelegate methods not called when UITableView is a subview of UIView (data initially loads) 【发布时间】:2014-03-25 15:09:52 【问题描述】:我有一个包含UITableView
的UIView
。这些由继承委托方法UITableViewDelegate
和NSFetchedResultsControllerDelegate
的UIViewController
管理。我可以使用NSFetchedResultsController
很好地填充表,但是当对fetchObjects
中的托管对象进行更改时,不会调用委托方法(特别是controllerWillChangeContent
)。
我已独立检查对对象进行了更改,并且我已在单元格中反映了这些更改,但是您必须手动重新加载单元格(向上滚动)才能看到更改发生。我正在寻找的行为是,当对对象进行更改(通过保存)时,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(使用 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;
设置 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】:contextChanged: 应该在 MainThread 上调用,因为它涉及 UI 更新。
【讨论】:
是的,我相信我正在确保if (![NSThread isMainThread]) [self performSelectorOnMainThread:@selector(contextChanged:) withObject:notification waitUntilDone:YES]; return;
是这种情况
你的 managedObjectContext 是否在主线程上改变了?如果没有,它不会触发 frc 委托。
@John 你不知道如果后台线程中的上下文发生变化如何触发委托方法吗?我的意思是我用 NSPrivateQueueConcurrencyType 创建新的上下文,设置父上下文并执行块,我将对象添加到 CoreData。以上是关于当 UITableView 是 UIView 的子视图时不调用 NSFetchedResultsControllerDelegate 方法(最初加载数据)的主要内容,如果未能解决你的问题,请参考以下文章
当 UITableView 枯竭时需要帮助显示自定义 UIView
当 UIView 的 needsUpdateConstraints 被调用时,UITableview 滚动到顶部[关闭]