【问题标题】:NSFetchedResultsController with NSPredicate带有 NSPredicate 的 NSFetchedResultsController
【发布时间】:2014-02-28 22:10:18
【问题描述】:

我正在使用 NSFetchedResultsController 来处理进出我的 UITableView 的数据。在我在上面放一个 NSPredicate 之前,一切都很好。我需要获取与至少一条未过期或尚未设置过期日期的消息有关系的所有 Thread 对象。所以我使用以下谓词。

NSPredicate *threadPredicate = [NSPredicate predicateWithFormat:@"ANY messages.expiration_date == null OR ANY messages.expiration_date > %@", [NSDate date]];

问题是这会导致 NSFetchedResultsController 表现得很奇怪。如果线程在其消息关系中获得一条新消息,它将删除该行。它也不会插入新的。

我 100% 确定是 NSPredicate 导致了这些行为。没有它,一切正常,我只是没有一些我不想过滤掉的数据。

下面是我的数据模型中讨论部分的图片。我还将包含我的 NSFetchedResultsController 的代码。

/**
 * Returns a NSFetchedResultsController for the unified inbox
 *
 * @return Controller for fetched results
 */
- (NSFetchedResultsController *)resultsControllerForUnifiedInbox
{
    NSFetchRequest      *threadsRequest = [NSFetchRequest fetchRequestWithEntityName:@"Thread"];
    NSEntityDescription *threadModel    = [NSEntityDescription entityForName:@"Thread" inManagedObjectContext:_mainManagedObjectContext];

    [threadsRequest setEntity:threadModel];

    NSPredicate *threadPredicate = [NSPredicate predicateWithFormat:@"ANY messages.expiration_date == null OR ANY messages.expiration_date > %@", [NSDate date]];

    [threadsRequest setPredicate:threadPredicate];

    NSSortDescriptor *threadSort = [NSSortDescriptor sortDescriptorWithKey:@"date" ascending:NO];

    [threadsRequest setSortDescriptors:[NSArray arrayWithObject:threadSort]];
    [threadsRequest setFetchBatchSize:LiftFetchControllerAtrributeBatchSize];

    NSFetchedResultsController *fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:threadsRequest
                                                                                               managedObjectContext:_mainManagedObjectContext
                                                                                                 sectionNameKeyPath:nil
                                                                                                          cacheName:nil];

    return fetchedResultsController;
}

【问题讨论】:

    标签: ios iphone core-data nspredicate nsfetchedresultscontroller


    【解决方案1】:

    我无法解释您观察到的谓词的奇怪效果,但我假设 你的谓词没有达到你的预期。

    [NSPredicate predicateWithFormat:@"ANY messages.expiration_date == null OR ANY messages.expiration_date > %@", [NSDate date]];
    

    找到所有具有未设置过期日期的消息或具有未过期的可能不同消息的线程。你(可能)需要的是

    [NSPredicate predicateWithFormat:@"SUBQUERY(messages, $m, $m.expiration_date == null OR $m.expiration_date > %@).@count > 0", [NSDate date]];
    

    【讨论】:

    • 太棒了,成功了。我将不得不研究这个 SUBQUERY 函数,它可以放在这样的 NSPredicate 中。谢谢!
    • @CodyRobertson:不幸的是,SUBQUERY 的文档记录很差。但是你会在NSExpression Class ReferenceexpressionForSubquery:usingIteratorVariable:predicate: 的文档中找到类似的案例。也许这有帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-12
    • 1970-01-01
    相关资源
    最近更新 更多