【发布时间】:2015-01-16 07:42:31
【问题描述】:
在应用程序重新启动或我转到另一个视图控制器并返回之前,我的 tableview 不会被 nsfetchedresultscontroller 中的数据填充。我以前从来没有遇到过这个问题,很奇怪。
代码:
- (void)viewDidLoad {
[super viewDidLoad];
self.tableView.contentInset = UIEdgeInsetsMake(0, 0, 60, 0);
[super viewDidLoad];
NSError *error;
if (![[self fetchedResultsController] performFetch:&error]) {
// Update to handle the error appropriately.
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
exit(-1); // Fail
}
UIRefreshControl *refresh = [[UIRefreshControl alloc] init];
[refresh addTarget:self
action:@selector(refresh)
forControlEvents:UIControlEventValueChanged];
self.refreshControl = refresh;
UITableViewController *tableVC = [[UITableViewController alloc]initWithStyle:UITableViewStylePlain];
[tableVC setTableView:self.tableView];
tableVC.refreshControl = self.refreshControl;
[self.tableView setContentOffset:CGPointMake(0.0f, -60.0f)
animated:YES];
[self getPosts];
// Do any additional setup after loading the view.
}
getPosts 为 tableview 拉入所有帖子并将它们保存到 coredata。
-(void)getPosts
{
[self.refreshControl beginRefreshing];
[self.postsController getPostsFeedWithCompletion:^(BOOL complete, NSArray *posts) {
[self.refreshControl endRefreshing];
} failure:^(NSString *message) {
[self.refreshControl endRefreshing];
ALAlertBanner *alert = [ALAlertBanner alertBannerForView:self.view
style:ALAlertBannerStyleFailure
position:ALAlertBannerPositionTop
title:@"Error"
subtitle:@"Error retrieving posts, please try again."];
[alert show];
}];
}
getPostsFeedWithCompletion 方法:
-(void)getPostsFeedWithCompletion:(void (^)(BOOL complete, NSArray *posts))complete
failure:(void (^)(NSString *message))failure
{
[[APIManager sharedManager] getPath:@"posts/feed"
parameters:nil
success:^(AFHTTPRequestOperation *operation, id responseObject) {
DLog(@"response: %@", responseObject);
NSArray __block *posts;
[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext){
posts = [self createPosts:responseObject[@"posts"] inContext:localContext];
} completion:^(BOOL success, NSError *error) {
if(complete){
complete(YES, posts);
}
}];
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
DLog(@"error: %@", error);
if(failure){
failure(@"Error retrieving posts");
}
}];
}
这里是 nsfetchedresultscontroller 实例化
- (NSFetchedResultsController *)fetchedResultsController {
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
NSManagedObjectContext *context = [NSManagedObjectContext MR_contextForCurrentThread];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:@"Post" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSArray *following = [[SessionManager getInstance].currentLoggedInUser.follows allObjects];
NSMutableArray *predicateArray = [NSMutableArray array];
NSDate *now = [NSDate date];
[predicateArray addObject:[NSPredicate predicateWithFormat:@"account IN %@", following]];
[predicateArray addObject:[NSPredicate predicateWithFormat:@"expiration > %@", now]];
NSCompoundPredicate *filterPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:predicateArray];
[fetchRequest setPredicate:filterPredicate];
[fetchRequest setFetchBatchSize:20];
NSSortDescriptor *sort = [[NSSortDescriptor alloc]
initWithKey:@"expiration" ascending:YES];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];
[fetchRequest setFetchBatchSize:20];
NSFetchedResultsController *theFetchedResultsController =
[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:context
sectionNameKeyPath:nil
cacheName:nil];
self.fetchedResultsController = theFetchedResultsController;
_fetchedResultsController.delegate = self;
return _fetchedResultsController;
}
这是 MagicalRecord 保存的日志:
[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0x7ffcea601bd0) → Saving <NSManagedObjectContext (0x7ffcea601bd0): *** UNNAMED ***> on *** BACKGROUND THREAD ***
[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0x7ffcea601bd0) → Save Parents? 1
[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0x7ffcea601bd0) → Save Synchronously? 1
[NSManagedObjectContext(MagicalRecord) MR_contextWillSave:](0x7ffcea601bd0) Context UNNAMED is about to save. Obtaining permanent IDs for new 22 inserted objects
[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0x7ffceba008f0) → Saving <NSManagedObjectContext (0x7ffceba008f0): *** DEFAULT ***> on *** BACKGROUND THREAD ***
[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0x7ffceba008f0) → Save Parents? 1
[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0x7ffceba008f0) → Save Synchronously? 1
[NSManagedObjectContext(MagicalRecord) MR_contextWillSave:](0x7ffceba008f0) Context DEFAULT is about to save. Obtaining permanent IDs for new 22 inserted objects
[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0x7ffcea746c10) → Saving <NSManagedObjectContext (0x7ffcea746c10): *** BACKGROUND SAVING (ROOT) ***> on *** MAIN THREAD ***
[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0x7ffcea746c10) → Save Parents? 1
[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0x7ffcea746c10) → Save Synchronously? 1
[NSManagedObjectContext(MagicalRecord) MR_contextWillSave:](0x7ffcea746c10) Context BACKGROUND SAVING (ROOT) is about to save. Obtaining permanent IDs for new 22 inserted objects
_70-[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:]_block_invoke21(0x7ffcea746c10) → Finished saving: <NSManagedObjectContext (0x7ffcea746c10): *** BACKGROUND SAVING (ROOT) ***> on *** MAIN THREAD ***
【问题讨论】:
-
我的猜测:您将数据保存在后台托管对象上下文中并且不将它们合并到主线程的上下文中?
-
@MichałCiuba 我正在后台线程上创建数据,但使用 [context MR_saveToPersistentStoreAndWait] 进行保存,这是我做过一千次但从未遇到过这个问题的方法
-
我不熟悉 MagicalRecord,但这会导致将数据合并到主线程的上下文中吗? NSFRC 使用该上下文。你实现
NSFetchedResultsControllerDelegate方法了吗?还有,这些行是干什么用的:UITableViewController *tableVC = [[UITableViewController alloc]initWithStyle:UITableViewStylePlain]; [tableVC setTableView:self.tableView];?据我所知,两个控制器不能共享他们的视图。 -
@MichałCiuba 它不是一个 tableviewcontroller 它是一个带有 tableview 的 uiviewcontroller。该代码添加了刷新控件
-
看起来根本没有调用任何 NSFetchedResultsController 委托方法。
标签: ios objective-c uitableview core-data nsfetchedresultscontroller