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

时间:2014-08-21 23:27:52

标签: ios objective-c core-data

我是Core Data(iOS 7)的新手,我试图从FMDB上的SQL切换到Core Data的数据获取方式。

我有一个条目实体,其数据如下:

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
-------------------------------------

我的最终目标是将这些数据呈现在一个tableView中,其中作为节标题,并且该年度的每个条目都按照相反的时间顺序列在其下面。所以数据看起来像这样:

-- 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)

这在SQL中很容易,但经过数小时的研究,这与Core Data中没有麻醉的心脏手术相似。

最后,我认为拥有像这样的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>
  }
}

...以正确的顺序准备传递给我的tableView委托。如何从Core Data对象获取时间排序和分组的字典数据而不会失去理智?

提前致谢。

3 个答案:

答案 0 :(得分:0)

  1. 创建NSFetchRequest。为日期列添加排序描述符。这将使您的行按顺序排列。
  2. 在您的托管对象上下文中执行获取请求,获取结果
  3. 将每个日期分解为组件(使用like this
  4. 迭代,构建数组,无论您需要做什么来按照您想要的格式按照结果。
  5. 1看起来像这样:

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

答案 1 :(得分:0)

核心数据存储NSDate。它们是不透明的,抽象的,时间戳。他们天生就不会有一年。根据您的时区和日历,相同的NSDate将显示不同的年份。

E.g。代表2001年1月1日GMT 00:01的NSDate将显示为&#39; 2001&#39;正确格式化时,在GMT手机上。它将显示为&#39; 2000&#39;在美国东部时间的电话。如果手机设置为使用中国日历而不是格里高利,它将再次显示为非常不同。

我不清楚为什么你会在SQL&#34;中轻松地考虑这个问题。可能你会以某种方式大规模地简化问题?

您可能希望添加一个瞬态属性来返回年份。这将是NSCalendar驱动的NSDate计算,包括获取NSDateComponents

您可以将sectionNameKeyPath的瞬态属性提供给NSFetchedResultsController

然而请注意语义:除非你检查表中的每一件事,否则你不知道岁月是什么。因此,您需要获取每一件事。出于性能原因,您可能希望明确告诉您的获取请求不返回错误*,因此您不会从Core Data的自动内存管理中获得任何好处。

(*)Core Data懒惰地在其图形中提取对象。查询通常会返回错误,这些错误是对原始对象的引用,因此可以找到它但不包含任何实际数据。但由于对属性的访问是同步的,如果你像填充的那样遍历错误,这意味着可怕的性能 - 核心数据无法预测你接下来要访问的对象,因此每次访问都是对持久性的单独访问存储。

答案 2 :(得分:0)

使用NSFetchedResultsController
您可以从Apple找到一个有效的示例!