在NSFetchedResultsController中使用sectionNameKeyPath时的顺序

时间:2014-07-28 14:59:21

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

在核心数据中,我有一对多的关系 - 每个布局都有很多行:

enter image description here

我试图通过分组到布局来显示表格视图中的数据:

Layout Nr 2342 (with orderPosition 1)
    Line 1
    Line 2
    Line …
Layout Nr 2123 (with orderPosition 2)
    Line 1
    Line …
…

我正在使用我创建的NSFetchedResultsController

NSEntityDescription *entity = [NSEntityDescription entityForName:@“Line” inManagedObjectContext:managedObjectContext];

NSSortDescriptor *orderPositionDescriptor = [[NSSortDescriptor alloc] initWithKey:@"layout.orderPosition" ascending:YES];

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setSortDescriptors:@[orderPositionDescriptor]];
[fetchRequest setEntity:entity];

NSPredicate *predicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:@"section=='my_section'"]];
[fetchRequest setPredicate:predicate];

self.fetchController = [[NSFetchedResultsController alloc]
                                          initWithFetchRequest:fetchRequest
                                          managedObjectContext:managedObjectContext
                                          sectionNameKeyPath:@"layout.groupNumber"
                                          cacheName:nil];

所以我将fetch控制器设置为按布局groupNumber分组,我还设置排序描述符按布局位置排序(每个布局都有自己的位置)。数据一旦添加到核心数据,它就会显示在表格视图中。一切都很好,直到我尝试更改现有NSFetchRequest的{​​{1}}谓词:

NSFetchedResultsController

我在谓词中设置了与已经设置完全相同的部分,并且表中显示的 NSPredicate *predicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:@"section=='%@'",section]]; [self.fetchController.fetchRequest setPredicate:predicate]; 之后的数据仍然相同,但布局(表格部分)更改了表格中的位置并显示了行在错误的布局(基本上没有奥德)。我想出如果我将第一个排序描述符设置为与sectionNameKeyPath相同 - " layout.groupNumber",那么即使我更改谓词,一切也都有效。但很明显,orderPosition没有按照我想要实现的目标进行排序。那有什么解决方案吗?任何帮助,将不胜感激。

2 个答案:

答案 0 :(得分:1)

如果在表视图中使用节,并对表视图数据进行排序,则必须了解第一个排序描述符必须与sectionNameKeyPath相同。

因此我建议您将代码更改为类似于此...

    NSEntityDescription *entity = [NSEntityDescription entityForName:@“Line” inManagedObjectContext:managedObjectContext];

//new line of code following...
    NSSortDescriptor *sectionNameDescriptor = [[NSSortDescriptor alloc] initWithKey:@"layout.groupNumber" ascending:YES];
    NSSortDescriptor *orderPositionDescriptor = [[NSSortDescriptor alloc] initWithKey:@"layout.orderPosition" ascending:YES];

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
//altered line of code following...
    [fetchRequest setSortDescriptors:@[sectionNameDescriptor, orderPositionDescriptor]];
    [fetchRequest setEntity:entity];

    NSPredicate *predicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:@"section=='my_section'"]];
    [fetchRequest setPredicate:predicate];

    self.fetchController = [[NSFetchedResultsController alloc]
                                      initWithFetchRequest:fetchRequest
                                      managedObjectContext:managedObjectContext
                                      sectionNameKeyPath:@"layout.groupNumber"
                                      cacheName:nil];

我已经读过这个但是不记得在哪里......所以没有文件参考我很抱歉。

这有帮助吗?

答案 1 :(得分:0)

我找到了解决问题的方法。由于每个布局组编号具有唯一的订单位置,因此解决方案不是按groupNumber分组,而是按orderPosition分组。在这种情况下,我可以将orderPosition指定为第一个(也是唯一的)排序描述符。如果其他人有其他更好的解决方案,听到它仍然会很有趣。

NSEntityDescription *entity = [NSEntityDescription entityForName:@“Line” inManagedObjectContext:managedObjectContext];

NSSortDescriptor *orderPositionDescriptor = [[NSSortDescriptor alloc] initWithKey:@"layout.orderPosition" ascending:YES];

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setSortDescriptors:@[orderPositionDescriptor]];
[fetchRequest setEntity:entity];

NSPredicate *predicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:@"section=='my_section'"]];
[fetchRequest setPredicate:predicate];

self.fetchController = [[NSFetchedResultsController alloc]
                                          initWithFetchRequest:fetchRequest
                                          managedObjectContext:managedObjectContext
                                          sectionNameKeyPath:@"layout.orderPosition"
                                          cacheName:nil];