简体   繁体   English

核心数据按年份分组并按日期排序

[英]Core Data Group By Year and Sort By Date

I'm new to Core Data (iOS 7), and I'm trying to make the switch from SQL on FMDB to Core Data's ways of fetching data.我是 Core Data (iOS 7) 的新手,我正在尝试从 FMDB 上的 SQL 切换到 Core Data 获取数据的方式。

I have an Entry entity that has data like this:我有一个条目实体,其中包含如下数据:

flightDate (date) |  duration (float)
-------------------------------------
  2014-05-21      |      1.0
  2014-08-03      |      2.0
  2013-03-27      |      3.0
  2013-09-16      |      4.0
  2012-12-20      |      5.0
-------------------------------------

My end goal is to render this data in a tableView with the year as the section title, and each entry for that year listed underneath it in reverse chronological order.我的最终目标是将这些数据呈现在 tableView 中,以年份作为部分标题,并按时间倒序在其下方列出该年份的每个条目。 So the data would look like this:所以数据看起来像这样:

-- 2014 --
Aug 3, 2014     (2.0)
May 21, 2014    (1.0)

-- 2013 --
Sep 16, 2013    (4.0)
Mar 27, 2013    (3.0)

-- 2012 --
Dec 20, 2012    (5.0)

This was easy peasy in SQL, but after hours of research, this is shaping up to be akin to heart surgery without anesthesia in Core Data.这在 SQL 中很容易实现,但经过数小时的研究,这正在变得类似于 Core Data 中没有麻醉的心脏手术。

In the end, I'm thinking it would be good to have an NSMutableDictionary like this:最后,我认为拥有这样的 NSMutableDictionary 会很好:

{
  2014 = {
    <Entry: Aug 3, 2014, 2.0>,
    <Entry: May 21, 2014, 1.0>  
  },
  2013 = {
    <Entry: Sep 16, 2013, 4.0>,
    <Entry: Mar 27, 2013, 3.0>  
  },
  2012 = {
    <Entry: Dec 20, 2012, 5.0>
  }
}

...in the right order and ready to pass to my tableView delegates. ...以正确的顺序并准备传递给我的 tableView 代表。 How can I get from Core Data objects to time-sorted and grouped dictionary data without losing my mind?如何从 Core Data 对象获取时间排序和分组的字典数据而不会失去理智?

Thanks in advance.提前致谢。

Use NSFetchedResultsController .使用NSFetchedResultsController
You can find a working example of breaking a table up into sections based on the date from Apple !您可以找到根据Apple的日期将表格分成多个部分的工作示例!

  1. Create an NSFetchRequest.创建一个 NSFetchRequest。 Add a sort descriptor for the date column.为日期列添加排序描述符。 That will get your rows in order.这将使您的行井然有序。
  2. Execute the fetch request on your managed object context, getting back your results在您的托管对象上下文上执行获取请求,取回您的结果
  3. Break each date into components (using something like this .将每个日期分解成组件(使用类似这样的.
  4. Iterate, build arrays, whatever you need to do to massage your results into the format you want.迭代、构建数组,无论您需要做什么来将结果转换为您想要的格式。

1 will look something like this: 1 看起来像这样:

NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Entry"];
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"flightDate" ascending:NO];
fetchRequest.sortDescriptors = @[sortDescriptor];

Core Data stores NSDate s.核心数据存储NSDate s。 They're opaque, abstract, timestamps.它们是不透明的、抽象的、时间戳。 They don't inherently have a year.他们天生就没有一年。 The same NSDate will display with a different year depending on your time zone and calendar.根据您的时区和日历,相同的NSDate将显示不同的年份。

Eg an NSDate that represents GMT 00:01 on the 1st of January, 2001 will display as '2001' on a phone in GMT when properly formatted.例如,如果格式正确,表示 2001 年 1 月 1 日 GMT 00:01 的NSDate将在 GMT 电话上显示为“2001”。 It will display as '2000' on a phone in EST.它将在 EST 的电话上显示为“2000”。 It will display as something very different again if the phone is set to use the Chinese calendar rather than the Gregorian.如果手机设置为使用中国日历而不是公历,它将再次显示为非常不同的内容。

It's unclear to me exactly why you would consider this "easy peasy in SQL".我不清楚为什么你会认为这个“SQL 中的简单易行”。 Probably you're massively simplifying the problem somehow?可能您正在以某种方式大规模简化问题?

You probably want to add a transient property to return the year.您可能想要添加一个临时属性来返回年份。 That will be an NSCalendar -driven calculation on the NSDate , involving getting the NSDateComponents .这将是NSDate上的NSCalendar驱动计算,涉及获取NSDateComponents

You can supply the transient property as the sectionNameKeyPath to an NSFetchedResultsController .您可以提供瞬态特性为sectionNameKeyPath一个NSFetchedResultsController

However notice the semantics: you don't know what the years are unless you inspect every single thing in the table.但是请注意语义:除非您检查表中的每一件事,否则您不知道年份是多少。 So you'll need to fetch every single thing.所以你需要获取每一件事。 You'll likely want explicitly to tell your fetch request not to return faults*, for performance reasons, and you're hence not going to get any benefit from Core Data's automatic memory management.出于性能原因,您可能希望明确告诉您的 fetch 请求不要返回错误*,因此您不会从 Core Data 的自动内存管理中获得任何好处。

(*) Core Data fetches objects within its graph lazily. (*) Core Data 懒惰地获取其图中的对象。 Queries ordinarily return faults, which are references to the original object so that it can be found but none of the actual data.查询通常会返回错误,这些错误是对原始对象的引用,因此可以找到它但找不到实际数据。 But since access to properties is synchronous, that means awful performance if you iterate through faults as though populated — Core Data can't predict which objects you're going to access next so each access is a separate trip to the persistent store.但是由于对属性的访问是同步的,如果您像填充一样遍历错误,这意味着糟糕的性能——Core Data 无法预测您接下来要访问哪些对象,因此每次访问都是对持久存储的单独访问。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM