使用 Core Data 时如何重新排列部分

Posted

技术标签:

【中文标题】使用 Core Data 时如何重新排列部分【英文标题】:How to rearrange sections, when using Core Data 【发布时间】:2012-05-19 18:09:44 【问题描述】:

有什么方法可以在不使用排序描述符的情况下重新排列使用 Core Data 的表视图的各个部分? 我需要的那种排序不是按字母顺序排列的,它会随时间变化(我已经读过,使用 Core Data,你不能使用自定义选择器作为排序描述符,所以默认选择器对我没有帮助)。

我有一个方法,当“部分重新排序”应该发生时被调用,我想知道是否有某种“索引向量”我可以修改,所以这些部分按该索引或类似的东西排序。 感谢您的帮助!

【问题讨论】:

【参考方案1】:

这里有两个选择:

1 您想在核心数据中排序的任何内容(并且,通过扩展,使用NSFetchedResultsController)您将需要以某种方式在您的数据中建模并使用排序描述符。

您声明(但未解释)“默认 [排序描述符] 对您没有帮助”。我想这意味着模型中包含的数据不足以进行重新排序。在这种情况下,您必须为相关实体引入一个新属性。这听起来可能需要付出太多努力,但通常并没有那么糟糕。

2 您可以将表视图的datasource 从获取的结果控制器更改为您自己的方案(例如,使用数组)。当然,存在内存影响,但这可能只是最简单的方法。

编辑 在您重申问题(循环向量排序)后,这里有一个建议:您可以使用sortDescriptorWithKey:ascending:comparator: 构造一个排序描述符,以准确提供您想要的结果。 (警告:未经测试的代码

int centerNumber = 2;  // or whatever your method returns
NSSortDescriptor *descriptor = [NSSortDescriptor 
     sortDescriptorWithKey:@"number" 
                 ascending:YES 
                  comparator:^(int a, int b) 
   NSComparisonResult r;
   if (a == b) r = NSOrderedSame;
   else if (a == centerNumber) r = NSOrderedAscending;
   else if (b == centerNumber) r = NSOrderedDescending;
   else if (abs(a-c) == abs(b-c))
      if (a<b) r = NSOrderedDescending;
      else r = NSOrderedAscending;
   else 
      if (abs(a-c) > abs(b-c)) r = NSOrderedAscending;
      else r = NSOrderedDescending;
   return r;
];

让我知道它是否有效。

编辑 2 如果您需要 NSNumber(这很可能是您的数据的存储方式),也许这可行:

...^(id x, id y) 
   int a = [x intValue];
   int b = [y intValue];
   ...
...

最终编辑

如果比较器不起作用,插入NSComparisonResult作为结果类型:

...comparator:^NSComparisonResult(id x, id y)....

【讨论】:

嗯,也许我遗漏了一些关于排序描述符的内容。我的模型中有一个属性存储一个数字(1 到 5),我想从需要重新排序时触发的方法指示的那个开始对它们进行排序。例如,如果方法说“2”,我希望这些部分按“2、3、1、4、5”排序。也就是说,首先是方法所说的那个,然后是 +1 和 -1,+2 -2 等,以“循环向量”的方式。这可以使用默认的排序描述符来完成吗? 可以使用自定义比较选择器来完成。查看我的编辑。 好的,我正在尝试将获取的结果控制器设置为处理具有此排序描述符的请求,但它不执行比较器!我已经在此之外测试了比较器,它可以工作,如果我在其中放置一个 NSLog,它就会被调用。但是,当将其设置为比较器时,它不会被调用,部分不会重新排序,并且控制台中没有 NSLog。我确定我正在以正确的方式设置获取的结果控制器(排序描述符的“升序”参数有效)。问题可能出在哪里? :S 也许 a 和 b 必须是 NSNumber 而不是 int。 这也不起作用。我试过这个:^(id a, id b) NSLog(@"Inside block"); return NSOrderedAscending; 并且 NSLog 没有被调用。但是,如果我调用 sortedArrayUsingComparator 将同一块传递给数组,则数组会被排序,并出现 NSLog。所以我猜核心数据不允许自定义比较器......关于如何解决这个问题的任何想法?

以上是关于使用 Core Data 时如何重新排列部分的主要内容,如果未能解决你的问题,请参考以下文章

持久化和重新排列 Core Data 记录的顺序

如何在重新进入查看时转储 Core Data 搜索结果 FRC?

如何根据 Core Data 中的关系对象创建 UITableView 部分

如何通过删除和重新安装 App 将数据持久化在 Core Data 中

如何在应用程序处于后台时执行 Core Data 操作

使用 Fetch Results Controller 对 Core Data 中的单元格重新排序