我知道我不是第一个提出这个问题的人,但我真的很难过......
基本上我有一个带两个按钮的屏幕。每个按钮根据日期将数据加载到下面的桌面视图中。在第一个tableview的第一次加载时(默认选中左键),一切正常。如果我点击右键,我得到一个空白的tableview,我收到错误
索引x处的获取对象具有无序部分名称 “XXXXXX。对象必须按部分名称排序。
切换回左表视图,数据消失了。两个tableviews都是空的。
每个tableview有2个部分,具体取决于项目的开始时间。如果我删除部分数据显示正常。不幸的是我需要它们..数据分为两部分,如:
@interface NSString(agendaSessionKeyPath)
@property (nonatomic, readonly) NSString *sessionSection;
@end
@implementation NSString(agendaSessionKeyPath)
- (NSString *)sessionSection
{
int timeValue = [[self stringByReplacingOccurrencesOfString:@":" withString:@""] intValue]; //turns 11:00 to 1100
if (timeValue < 1200)
return @"Morning";
else
return @"Afternoon";
}
获取请求
- (void)viewDidLoad
{
//other viewDidLoad stuff
[self fetchSessions];
}
根据日期从左右按钮对数据进行排序的方法:
- (void)fetchSessions
{
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
[dateFormatter setDateFormat:@"yyyy-MM-dd"];
NSDate* date = nil;
if (selected == 0) //left button is selected
{
date = [dateFormatter dateFromString:@"2012-09-26"];
}
else if (selected == 1) //right button is selected
{
date = [dateFormatter dateFromString:@"2012-09-27"];
}
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"date == %@", date];
[self.fetchedResultsController.fetchRequest setPredicate:predicate];
NSError *error;
if (![[self fetchedResultsController] performFetch:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
}
}
获取结果控制器
- (NSFetchedResultsController *)fetchedResultsController {
self.managedObjectContext = [[MATCDatabaseController sharedDatabaseController] managedObjectContext];
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Session"];
NSSortDescriptor *sort = [[NSSortDescriptor alloc]
initWithKey:@"title" ascending:YES];
NSSortDescriptor *timeSort = [NSSortDescriptor sortDescriptorWithKey:@"timeValue" ascending:YES];
[fetchRequest setSortDescriptors:@[timeSort, sort]];
[fetchRequest setFetchBatchSize:20];
NSFetchedResultsController *theFetchedResultsController =
[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"startTime.sessionSection"
cacheName:nil];
self.fetchedResultsController = theFetchedResultsController;
[self.fetchedResultsController setDelegate:self];
return _fetchedResultsController;
}
任何帮助表示赞赏!
答案 0 :(得分:22)
好的,我确实快速看了一眼。
使用以下命令初始化FRC:
[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:self.managedObjectContext
sectionNameKeyPath:@"startTime.sessionSection"
cacheName:nil];
告诉它你的章节标题是通过关键路径startTime.sessionSection
获得的。
现在,给予FRC的获取请求的第一个排序描述符将用于对这些部分进行排序。您首先提供的排序描述符适用于timeValue
,这似乎不正确。
您的第一个排序描述符应指定节标题的排序。改变这一点,你可能会很高兴。
修改强>
谢谢大家的信息。我虽然还有点失落。你的意思是 我应该在startTime.sessionSection之前添加一个排序描述符 将它分配给sectionNameKeyPath?我试过了,但还是没有运气。 timeValue和startTime.sessionSection是相关的。可能是吗? - 发牢骚
您必须确保第一个排序描述符将根据该部分正确排序数据。在你的情况下,时间被转换成单词。您的初始排序描述符是有时间的,当数据按时间排序时,这些部分没有正确排序,这会导致您的错误。
第一个排序描述符必须满足节数据。所以,最初,我会尝试......
[fetchRequest setSortDescriptors:@[
[NSSortDescriptor sortDescriptorWithKey:@"startTime.sessionSection"
ascending:NO],
[NSSortDescriptor sortDescriptorWithKey:@"timeValue"
ascending:YES],
[NSSortDescriptor sortDescriptorWithKey:@"title"
ascending:YES] ];
注意,如果您有大量的数据,您可能会发现您的部分机制变慢。如果发生这种情况,您可能希望将此部分数据添加到数据库中。
答案 1 :(得分:0)
我也有类似的问题,也许有人觉得它很有用。
我从数据库中获取了财务交易,并按月划分了它们。
DB具有属性trDate - 这是一个交易日期。但是trMonth是一个短暂的属性,如:
- (NSString*)trMonth {
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"LLLL"];
[dateFormatter setLocale:[NSLocale currentLocale]];
return [dateFormatter stringFromDate:trDate];
}
它在FetchResultsController中使用如下:
...
NSSortDescriptor *sortDate = [[NSSortDescriptor alloc] initWithKey:@"trDate" ascending:YES];
[fetchRequest setSortDescriptors:@[sortDate]];
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"trMonth" cacheName:nil];
...
哪个在生产中运作良好,但是一旦应用程序开始崩溃,并且在发现根问题之后我发现在7月:2014年7月和2015年7月有两个交易(例如)。那就是崩溃点为trDate 2014年7月排序好&lt; 2015年7月,但我的方法将它们视为同月。该解决方案不仅用作月份名称,还用作年份:
- (NSString*)trMonthYear {
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"LLLL yyyy"]; // added year also
[dateFormatter setLocale:[NSLocale currentLocale]];
return [dateFormatter stringFromDate:trDate];
}