我使用NSFetchedResultsController管理了一个tableview,其获取请求对日期属性使用简单排序。它在第一次加载时排序正确,但是当我刷新或调用loadMore
方法(见下文)时,排序顺序随机出现。
NSFetchedResultsController方法
- (NSFetchedResultsController *)getFetchedResultsController {
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
[NSFetchedResultsController deleteCacheWithName:@"LatestNews"];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:@"News" inManagedObjectContext:self.managedObjectContext]];
[request setFetchLimit:kDefaultNewsLimit];
[request setFetchBatchSize:20];
[request setIncludesPropertyValues:NO];
NSSortDescriptor *dateSortor = [NSSortDescriptor sortDescriptorWithKey:@"dateAdded" ascending:NO];
[request setSortDescriptors:[NSArray arrayWithObject:dateSortor]];
_fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:@"LatestNews"];
_fetchedResultsController.delegate = self;
return _fetchedResultsController;
}
loadMore方法
- (void)loadMore {
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
UIActivityIndicatorView *loadingIndicator = (UIActivityIndicatorView *)[loadMoreButton viewWithTag:3];
[loadingIndicator startAnimating];
NSUInteger newsLoaded = self.numberOfLimitedNews;
double delayInSeconds = 1.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
//fetch news from internet with date args
NSDate *lastNewsDate;
NSDate *beginTime, *endTime;
NSDictionary *condition;
[self.fetchedResultsController.fetchRequest setFetchLimit:self.numberOfLimitedNews+kDefaultNewsLimit];
[NSFetchedResultsController deleteCacheWithName:@"LatestNews"];
[self.fetchedResultsController performFetch:nil];
if (self.numberOfLimitedNews - newsLoaded < kDefaultNewsLimit) {
News *lastNews = [newsHelper getLastNews:@"LatestNews" idValue:nil];
lastNewsDate = lastNews.dateAdded;
beginTime = [NSDate dateWithTimeIntervalSince1970:0];
if (!lastNewsDate) {
endTime = [NSDate date];
}
else {
endTime = lastNewsDate;
}
condition = [NSDictionary dictionaryWithObjectsAndKeys:beginTime, @"beginTime", endTime, @"endTime", nil];
NSUInteger newsToFetch = kDefaultNewsLimit - self.numberOfLimitedNews % kDefaultNewsLimit;
[newsHelper getNumberOfNews:newsToFetch forLanguages:@"en" withCondition:condition];
[self.fetchedResultsController.fetchRequest setFetchLimit:self.fetchedResultsController.fetchRequest.fetchLimit+newsToFetch];
}
[self.tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:YES];
});
}
结果:
2011-09-13 16:48:20.959 HJNews[5971:bc03] 2011-02-04 06:00:00 +0000
2011-09-13 16:48:21.079 HJNews[5971:bc03] 2011-09-13 08:29:48 +0000
2011-09-13 16:48:21.230 HJNews[5971:bc03] 2011-02-19 01:30:00 +0000
2011-09-13 16:48:21.463 HJNews[5971:bc03] 2011-09-13 08:45:00 +0000
2011-09-13 16:48:21.879 HJNews[5971:bc03] 2011-03-06 02:00:00 +0000
2011-09-13 16:48:22.143 HJNews[5971:bc03] 2010-12-01 02:40:00 +0000
2011-09-13 16:48:22.229 HJNews[5971:bc03] 2011-09-13 02:03:43 +0000
2011-09-13 16:48:22.313 HJNews[5971:bc03] 2011-09-13 08:10:33 +0000
2011-09-13 16:48:22.446 HJNews[5971:bc03] 2011-01-02 06:00:00 +0000
2011-09-13 16:48:22.627 HJNews[5971:bc03] 2011-09-13 08:45:00 +0000
2011-09-13 16:48:22.978 HJNews[5971:bc03] 2011-01-23 02:00:01 +0000
2011-09-13 16:48:23.092 HJNews[5971:bc03] 2011-09-13 03:35:40 +0000
2011-09-13 16:48:23.196 HJNews[5971:bc03] 2011-02-18 06:20:00 +0000
2011-09-13 16:48:23.346 HJNews[5971:bc03] 2011-09-13 00:00:00 +0000
2011-09-13 16:48:23.812 HJNews[5971:bc03] 2011-02-08 06:00:00 +0000
2011-09-13 16:48:23.980 HJNews[5971:bc03] 2011-09-12 01:40:10 +0000
2011-09-13 16:48:24.179 HJNews[5971:bc03] 2011-01-18 06:00:00 +0000
2011-09-13 16:48:26.257 HJNews[5971:bc03] 2010-12-22 06:30:00 +0000
2011-09-13 16:48:27.783 HJNews[5971:bc03] 2011-02-08 06:00:00 +0000
2011-09-13 16:48:27.784 HJNews[5971:bc03] 2011-09-12 01:40:10 +0000
2011-09-13 16:48:27.785 HJNews[5971:bc03] 2011-01-18 06:00:00 +0000
2011-09-13 16:48:27.785 HJNews[5971:bc03] 2010-12-22 06:30:00 +0000
2011-09-13 16:48:27.786 HJNews[5971:bc03] 2011-09-13 02:10:17 +0000
从互联网
获取数据后调用的方法- (void)asiRequestFinished:(NSNotification *)notification {
dispatch_async(dispatch_get_main_queue(), ^{
[NSFetchedResultsController deleteCacheWithName:@"LatestNews"];
[self.fetchedResultsController performFetch:nil];
[self.tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:YES];
UIActivityIndicatorView *loadingIndicator = (UIActivityIndicatorView *)[loadMoreButton viewWithTag:3];
[loadingIndicator stopAnimating];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
isRefreshing = NO;
[refreshView egoRefreshScrollViewDataSourceDidFinishedLoading:self.tableView];
});
}
答案 0 :(得分:4)
首先,您尝试在另一个没有意义的队列上运行获取结果控制器(FRC)。不要混淆从网络下载数据与从本地持久性存储文件中获取数据。
网络操作可以在后台执行,但与FRC相关的UI操作需要位于前台。如果在另一个队列中修改FRC,它将与tableview不同步。
其次,您必须删除FRC的缓存,并在 之后调用其performFetch
,以便对获取请求进行任何更改。在某些情况下,您之后会更改fetchLimit
。这可能会产生不可预测的行为(尽管在这种情况下,这种变化似乎毫无意义,因为它从未使用过。)
我建议从队列中删除FRC代码,而只是让它以标准方式响应对另一个队列所做的更改。然后我会清理对获取请求的更改。最后,我会摆脱获取限制。他们很少提高效率,甚至更少,所以当你有各种各样的时候。
答案 1 :(得分:-2)
似乎已经解决了。当应用程序之前输入到后台时,我将数据保存到Core Data。现在我从互联网下载数据后保存它。