【问题标题】:Order when using sectionNameKeyPath in NSFetchedResultsController在 NSFetchedResultsController 中使用 sectionNameKeyPath 时的顺序
【发布时间】:2014-07-28 14:59:21
【问题描述】:

在 Core Data 中,我有一对多的关系——每个布局都有很多行:

我正在尝试通过分组布局在表格视图中显示数据:

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 分组,我还将排序描述符设置为按布局位置排序(每个布局都有自己的位置)。一旦数据被添加到核心数据中,它就会显示在表格视图中。一切正常,直到我尝试更改现有 NSFetchedResultsControllerNSFetchRequest 谓词:

 NSPredicate *predicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:@"section=='%@'",section]];
 [self.fetchController.fetchRequest setPredicate:predicate]; 

我在谓词中设置了与已经设置完全相同的部分,并且表格中显示的performFetch之后的数据仍然相同,但是布局(表格部分)在表格中更改了位置并且行显示错误布局(基本上无序)。我发现如果我将第一个排序描述符设置为与 sectionNameKeyPath -“layout.groupNumber”相同,那么即使我更改谓词也一切正常。但显然它不是按我想要实现的 orderPosition 排序的。有什么解决办法吗?任何帮助,将不胜感激。

【问题讨论】:

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


    【解决方案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];
    

    我已经阅读过这方面的内容,但不记得在哪里......所以很抱歉没有文档参考。

    这有帮助吗?

    【讨论】:

    • 感谢您的帮助,但正如我在问题中已经提到的那样:“如果我将第一个排序描述符设置为与 sectionNameKeyPath - layout.groupNumber 相同,那么即使我更改谓词也一切正常”。如果我的第一个排序顺序描述符是 groupNumber,那么即使 orderPosition 设置为第二个排序描述符,排序也会出错(数据将按组号排序)。
    • 啊抱歉@sash 没有仔细阅读...我再看看 :)
    【解决方案2】:

    我找到了解决问题的方法。因为每个布局组号都有唯一的订单位置,所以解决的办法不是按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];
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-15
      • 2011-05-24
      • 2014-07-30
      • 1970-01-01
      • 1970-01-01
      • 2013-10-21
      • 2011-09-30
      • 1970-01-01
      相关资源
      最近更新 更多