【问题标题】:Bizarre issue - "The fetched object at index x has an out of order section name"奇怪的问题 - “索引 x 处的获取对象的部分名称乱序”
【发布时间】:2013-08-20 19:18:17
【问题描述】:

我收到以下错误消息:

CoreData: error: (NSFetchedResultsController) The fetched object at index 5 has an out of order section name 'James. Objects must be sorted by section name'
Unresolved search error Error Domain=NSCocoaErrorDomain Code=134060 "The operation couldn’t be completed. (Cocoa error 134060.)" UserInfo=0xaa07530 {reason=The fetched object at index 5 has an out of order section name 'James. Objects must be sorted by section name'}, {
    reason = "The fetched object at index 5 has an out of order section name 'James. Objects must be sorted by section name'";
}

我已经阅读了无数关于 SO 的答案,这些答案大多最终指向使用不区分大小写的比较作为答案,但是正如您在下面看到的那样,我的 fetch 请求已经设置为执行此操作:

<NSFetchRequest: 0xc082bd0> (entity: InviteeModel; predicate: (eventId == 148 AND typeOf != "InviteeTypeOfServerContact"); sortDescriptors: ((
    "(lastName, ascending, caseInsensitiveCompare:)",
    "(firstName, ascending, caseInsensitiveCompare:)"
)); batch size: 1000; type: NSManagedObjectResultType; )

我似乎已将其范围缩小到我有两个姓氏相同的受邀者(即 HENRY JAMES 和 Henry James)的情况,然后我收到上面的错误,说 James 出现故障。如果我将两个姓氏都更改为 James 或 JAMES,那么它可以工作吗?!?!?

这是创建获取请求的代码:

NSFetchRequest *fetchRequest = [self buildFetchRequest];

// We have to reset the fetched results controller if the sort changes.
// Because otherwise the scrolling index will be inaccurate.
if (self.fetchedResultsController) {
    if (![self.fetchedResultsController.sectionNameKeyPath isEqualToString:self.sortBy]) {
        self.fetchedResultsController = nil;
    }
}


if (!self.fetchedResultsController) {

    NSManagedObjectContext *context = self.event.managedObjectContext;

    NSString *sectionNameKeyPath = nil;
    if (self.sortBy == DefaultSortBy) {

        sectionNameKeyPath = @"sectionChar";
    }
    else {

        sectionNameKeyPath = self.sortBy;
        if ([self.sortBy isEqualToString:@"rsvpState"] || [self.sortBy isEqualToString:@"checkedIn"]) {
            sectionNameKeyPath = @"lastName";
        }
    }

    NSFetchedResultsController *fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest 
                                                                                               managedObjectContext:context 
                                                                                                 sectionNameKeyPath:sectionNameKeyPath
                                                                                                          cacheName:nil];
    fetchedResultsController.delegate = self;
    self.fetchedResultsController = fetchedResultsController;

这是来自 buildFetchRequest 的一个片段,它添加了 sortDescriptors:

        NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:self.sortBy
                                                                       ascending:self.shouldSortAscending
                                                                        selector:@selector(caseInsensitiveCompare:)];

        // Add the default sorts (last, first).
        NSSortDescriptor *lastSort = nil;
        NSSortDescriptor *firstSort = nil;
        if (![self.sortBy isEqualToString:@"lastName"]) {
            lastSort = [NSSortDescriptor sortDescriptorWithKey:@"lastName"
                                                     ascending:YES
                                                      selector:@selector(caseInsensitiveCompare:)];
        }
        if (![self.sortBy isEqualToString:@"firstName"]) {
            firstSort = [NSSortDescriptor sortDescriptorWithKey:@"firstName"
                                                      ascending:YES
                                                       selector:@selector(caseInsensitiveCompare:)];
        }

        NSArray *sorts = nil;

        if (lastSort && firstSort) {
            sorts = [[NSArray alloc] initWithObjects:sortDescriptor, lastSort, firstSort, nil];
        }
        else if (lastSort) {
            sorts = [[NSArray alloc] initWithObjects:sortDescriptor, lastSort, nil];
        }
        else {
            sorts = [[NSArray alloc] initWithObjects:sortDescriptor, firstSort, nil];
        }

        [fetchRequest setSortDescriptors:sorts];

任何想法,这让我发疯。

【问题讨论】:

  • 你能 NSLog 完整的 fetchedResultsController 吗?
  • @MartinR,感谢您的帮助。您在我可以打印出来的 frc 中是否有任何特定的内容?它是一个大对象,并且 nslogging 它只给了我地址。
  • 我的主要问题是 sectionNameKeyPath 和第一个排序描述符是否总是使用相同的键。从您的代码中对我来说并不明显。

标签: ios core-data nsfetchedresultscontroller


【解决方案1】:

您正在设置与第一个排序描述符键不同的提取结果控制器部分名称键路径。

   NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] 
           initWithKey:self.sortBy 
           ascending:self.shouldSortAscending
           selector:@selector(caseInsensitiveCompare:)];

密钥是self.sortBy。

if ([self.sortBy isEqualToString:@"rsvpState"] || 
    [self.sortBy isEqualToString:@"checkedIn"]) {
       sectionNameKeyPath = @"lastName";
}

密钥不是 self.sortBy。

这应该会导致您看到的错误。

【讨论】:

  • 嗨@Mundi,我已经打印出 self.sortBy 和 FRC sectionNameKeyPath 的值,即使出现错误,它也始终是“lastName”,所以我不确定是不是这样?跨度>
  • 同时打印出你的第一个排序描述符的关键路径并进行比较。
【解决方案2】:

嗯,关键问题是哪个属性在确定 sectionNameKeyPath 以及该属性是否已用作排序描述符数组中的第一个排序描述符。

我想这是检查您是否遇到此类问题的第一件事。

【讨论】:

    猜你喜欢
    • 2011-03-09
    • 2012-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-30
    • 2012-05-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多