UITableViews 上的核心数据关系和/或 NSPredicate 排序

Posted

技术标签:

【中文标题】UITableViews 上的核心数据关系和/或 NSPredicate 排序【英文标题】:Core Data relationship and/or NSPredicate sorting on UITableViews 【发布时间】:2013-09-06 23:23:26 【问题描述】:

我遇到了一个应该非常基本并且有一个明显答案的问题,我已经阅读了一些 Apple 的文档以及此处的答案和在线教程。

我有一个显示“月份”实体列表的表格视图(应用程序使用核心数据)。它连接到另一个表格视图,我想显示该父月份中包含的所有日期的列表。因此,在“月份”实体列表中点击一行,理想情况下只列出一月份的日子。

Month 和 Days 表格视图都与常规视图控制器(不是 tableview VC)有单独的 segue,分别添加 Month 条目和 Day 条目。

数据经过建模,因此 Month 具有以 Days 为目标的一对多关系 (daysInMonths),而反之则是一对一关系 (parentMonth)。

月份属性是“月”和“年”。天属性是“月”、“日”和“年”。

模型对象上的所有属性目前都是字符串(不理想,但我会在下一个练习中更改它)。

我可以添加月份和日期条目。我可以删除它们。问题是,当我在第一个表视图(月)中点击一行时,它会显示每天的条目,根本没有过滤。

我假设当我在 Days tableview .m 文件中设置获取结果控制器时,我将使用谓词仅过滤与给定父月份匹配的日期。

我在这个 tableview 中的获取请求是在 Days 对象上的。设置谓词时,我是否必须在该 fetch 方法中实例化 Month 对象?

当我想要做的只是设置“parentMonth”关系以正确关联数据时,我不想创建显示在 tableview 中的其他 Model 对象。

我从概念上理解关系的概念,但我有点不清楚如何在代码中实际设置它们。

设置这种过滤器的最佳位置是什么?

我意识到我可能不够清楚,所以我会尽我所能回答任何其他问题。

我知道我缺少一些基本的东西,因为这种功能无处不在,但我自己的阅读还没有让我明白这一点......

@implementation DaysCDTVC

- (void)setupFetchedResultsController
    
    // 1 - Get Entity 
    NSString *entityName = @"Days";
    NSLog(@"Setting up a Fetched Results Controller for the Entity named %@", entityName);

    // 2 - Request 
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:entityName];

    // 3 - Filter 

    //request.predicate = [NSPredicate predicateWithFormat: ????????????????

    // 4 - Sort 
    request.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor     sortDescriptorWithKey:@"month"
                                                                                   ascending:YES
                                                                                  selector:@selector(localizedCaseInsensitiveCompare:)]];    

    //5 - Fetch 
    self.fetchedResultsController = [[NSFetchedResultsController alloc]   initWithFetchRequest:request
                                                                      managedObjectContext:self.managedObjectContext
                                                                          sectionNameKeyPath:nil
                cacheName:nil];

    [self performFetch];    

“performFetch”方法在关联的类中。这与 Paul Hegarty 在斯坦福 iTunes 讲座中所教的内容基本相同。

【问题讨论】:

显示您的 FRC 的代码 我正在为您制定解决方案,但是您的 Days 对象不应具有月份属性。它应该只从它与月份对象的关系中获取它的月份。这将使您的获取为您工作。 这很有趣。既然你提到它,那是有道理的。谢谢你。 【参考方案1】:

我从自己的一个项目中转置了代码。这应该可以解决您的问题。如果您需要澄清或有问题,请告诉我。

在您的 days 表格视图控制器中,创建一个公共属性:

@property (nonatomic, strong) NSString *month;

month 表视图控制器中,将所选月份传递给 days 表视图控制器:

- (void)prepareForSegue

    //Get a pointer to the destination TVC.
    //Your final code should have a check to make sure the destination TVC is what you expect
    DaysTableViewController *destinationTVC = (DaysTableViewController*)segue.destinationViewController;

    //Pass over the month from the selected row.  I'm calling it selected month.
    //If you need help getting the selected month, let me know
    destinationTVC.month = selectedMonth

days 表格视图控制器中,使用过去的月份构建您的获取请求

- (void)setupFetchedResultsController

    //Entity
    NSString *entityName = @"Days";

    //Fetch Request
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:entityName];

    //Sort
    request.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"day" ascending:YES]];

    //Predicate
    request.predicate = [NSPredicate predicateWithFormat:@"ANY SELF.month = %@", self.month];

    //Fetch using the code you posted earlier

【讨论】:

显然我处理事情的速度很慢。我会尽快尝试这个。看了看,我理解了cmets,所以我充满希望。我非常感谢您的努力,并将尽快将其标记为“已接受”。这很棒。感谢您帮助我继续学习。 很高兴为您提供帮助。我从帮助我的人那里学到了大部分我所知道的。如果您需要帮助,请告诉我。 感谢您的帮助 jb_OH,我能够获得该应用程序的粗略副本。当然这不太实用,因为所有模型属性都是字符串,并且需要在代码中添加 if/else 检查。但老实说,非常感谢。我确实不得不在谓词中省略 ANY 语句,因为它抛出了错误,抱怨 ANY 和 ALL 语句的左侧是一个数组或集合。 Month 与 Days 有一对多的关系,反之亦然。我必须阅读并了解有关谓词的更多信息。

以上是关于UITableViews 上的核心数据关系和/或 NSPredicate 排序的主要内容,如果未能解决你的问题,请参考以下文章

一个 UIView 上的多个 UITableViews

ScrollView 或 UICollectionView 中的 UItableViews? [关闭]

试图理解核心数据关系或处理重复

有序核心数据关系 - 如何管理或默认排序是什么?

数据插入上的核心数据级联

核心数据关系