NSFetchedResultsController 仅按第一个排序描述符排序

Posted

技术标签:

【中文标题】NSFetchedResultsController 仅按第一个排序描述符排序【英文标题】:NSFetchedResultsController only sorting by 1st sort descriptor 【发布时间】:2012-08-12 19:48:30 【问题描述】:

我发现 NSFetchedResultsController 仅在数据更改时按 sortDescriptors 数组中的第一个 NSSortDescriptor 排序的问题。真是气死人了。

我正在使用 NSFetchedResultsController 来管理显示项目列表的表格视图。这些项目具有基于number 属性的固有顺序,但用户可以收藏项目。收藏的项目显示在表格视图的顶部,按number 属性排序。

所以,模型看起来像这样:

@interface Thing : NSManagedObject
    @property (nonatomic, retain) NSNumber *number;
    @property (nonatomic, retain) NSNumber *favorite;
@end

@implementation Thing
    @dynamic number;
    @dynamic favorite;
@end

我正在像这样配置我的NSFetchedResultsController

- (void)loadView 
    ...
    //
    // configure fetched results controller for the things table view
    NSFetchRequest *fetchThings = [[NSFetchRequest alloc] init];
    fetchChannels.entity = [NSEntityDescription entityForName:NSStringFromClass([Thing class]) 
                                       inManagedObjectContext:[DataManager sharedInstance].managedObjectContext];
    fetchThings.sortDescriptors = @[
    [NSSortDescriptor sortDescriptorWithKey:@"favorite" ascending:NO],
    [NSSortDescriptor sortDescriptorWithKey:@"number" ascending:YES] ];
    
    _fetchController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchThings
                                                           managedObjectContext:[DataManager sharedInstance].managedObjectContext
                                                             sectionNameKeyPath:nil
                                                                      cacheName:nil];
    
    NSError *error = nil;
    if (![_fetchController performFetch:&error]) 
        NSLog(@"error performing fetch! %@", error.localizedDescription);
    

最初加载表格时,_fetchController 正确地对项目进行排序,因此您最终可能会得到如下结果:

- Thing: favorite = YES, number = 2
- Thing: favorite = YES, number = 3
- Thing: favorite = NO, number = 1
- Thing: favorite = NO, number = 4

但如果您取消收藏第 2 个事物,它只会按第一个排序描述符排序,列表如下所示:

- Thing: favorite = YES, number = 3
- Thing: favorite = NO, number = 2
- Thing: favorite = NO, number = 1
- Thing: favorite = NO, number = 4

有没有人遇到过这个问题或找到了解决方法?

更新

看来,如果我喜欢 everything,然后不喜欢 everything,排序会自行解决。这让我相信这可能是一个错误的问题?不幸的是,我也不确定如何解决这个问题。

【问题讨论】:

【参考方案1】:

好吧,我想通了,这是我自己的错。

仅仅因为该字段代表BOOL 并不意味着它实际上是BOOLThing 模型中的 favorite 字段实际上是 NSNumber,因此具有 3 个状态,@(YES)@(NO)nil。一旦我确定我正在正确初始化 favorite 字段,排序就会再次按预期工作。

【讨论】:

你完全正确。我在排序时遇到了同样的问题,并且还认为 NSNumber 中的布尔值可以有 3 种状态 YES、NO 和 nil。

以上是关于NSFetchedResultsController 仅按第一个排序描述符排序的主要内容,如果未能解决你的问题,请参考以下文章

在 Core Data 应用程序中调用 performFetch 后,是不是需要手动更新表视图?