使用NSFetchedResultsController动态创建节 [英] Creating sections with NSFetchedResultsController, on the fly

查看:93
本文介绍了使用NSFetchedResultsController动态创建节的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 NSFetchedResultsController (NSFRC)在 UITableView 中显示信息。我正在尝试为用户创建选项,以便按部分而不是按字母顺序对单元格进行排序。问题是,然后使用下载的信息确定部分。除此之外,每个项目的部分将相对经常更改,因此我不想保存该部分。在我对类似问题的研究中,我注意到了瞬态属性的提及,但是在我不确定是否可以使用它们之前我从未使用过它们,因为所有的计算都是在数据加载完成后完成的,我也希望这个解决方案与我之前的核心数据数据库兼容。另外,我不是特别擅长核心数据,(也不是 Objective-C )所以我是我不完全确定如何做到这一点。

I'm using NSFetchedResultsController (NSFRC) to display information in a UITableView. I'm trying to create the option for the user to sort the cells in sections as opposed to alphabetically. The problem is, the sections would then be determined using downloaded information. On top of this the section for each item will be changing relatively often so I don't want to save the section. I have noticed the mention of transient attributes, in my research of similar problems, but i've never used these before I'm not sure if I can use them baring in mind that all the calculations are done once the data has already been loaded, and I also want this solution to be compatible with my previous Core Data database. Also I'm not particularly great at Core Data, (nor Objective-C at that!) so I'm not entirely sure how I'd go about doing this.

所以这就是我想要的东西,如果我们使用瞬态属性(下一位理论上就是我不知道瞬态属性是否是正确的前进方式)。我想要4个可能的部分,0-3(我将使用 TableView委托重命名它们以解决排序问题)。完成计算后,将为每个单元格分配瞬态属性(如果需要,默认部分为2)。我希望这一切都有意义。

So here's what I want to go for if we're using transient attributes (this next bit is theoretical as I don't know if transient attributes are the correct way forward). I would like 4 possible sections, 0-3 (I'll rename them using the TableView delegate to get around sorting problems). When the calculations are done, each cell will be assigned the transient attribute (if needed, the default section would be 2). I hope this all makes sense.

是的,现在是一些理论代码。首先,我在数据模型屏幕中创建瞬态属性,并通过检查瞬态复选框使其瞬态...听起来很简单。

Right, now for some theoretical code. First I create the transient property in the Data Model screen-thing, and make it transient by checking the transient check box... Sounds simple enough.

中计算的代码willDisplayCell (由于几个原因需要在wDC中完成),该实体可以像这样保存:

In the code for the calculations in willDisplayCell (needs to be done in wDC for a couple of reasons), the entity could be saved like this:

MyEntity *myEntity = [self.fetchedResultsController objectAtIndexPath:indexPath];

myEntity.sectionTransientProperty = 2;

if (![self.managedObjectContext save:&error]) {
    NSLog(@"Error: %@", error);
    FATAL_CORE_DATA_ERROR(error);
    return;
}  

完成,对吧?我们如何为瞬态属性赋值?

Done, right? Is that how we assign a value to a transient property?

然后我在分配时更改NSFRC中的排序选项:

Then I change the sorting option in NSFRC when I alloc it:

fetchedResultsController = [[NSFetchedResultsController alloc]
                                initWithFetchRequest:fetchRequest
                                managedObjectContext:self.managedObjectContext
                                sectionNameKeyPath:@"sectionTransientProperty"
                                cacheName:@"MyEntity"];

我们如何做,我还需要做什么?或者我有这么可怕的错误我应该放弃核心数据和NSFRC?如果你们可以帮助指导我完成这个我真的很感激。如果您需要我发布任何更多代码,我会很高兴。

How are we doing, what else do I need to do? Or have I got this so horribly wrong I should just give up on Core Data and NSFRC? If you guys could help guide me through this I'd really appreciate it. If you need me to post any more code I would be happy to.

问候,

Mike

Regards,
Mike

推荐答案

如果你想要一个带有部分的FRC,你必须在获取请求中添加一个排序描述符,并且该排序描述符不能基于瞬态属性。

If you want an FRC with sections, you have to add a sort descriptor to the fetch request, and that sort descriptor cannot be based on transient attributes.

请参阅 initWithFetchRequest:managedObjectContext:sectionNameKeyPath:cacheName:`:


如果控制器生成节,
中的第一个排序描述符数组用于将对象分组为多个节;它的键必须
与sectionNameKeyPath相同或相对排序
使用其键必须与使用sectionNameKeyPath匹配。

If the controller generates sections, the first sort descriptor in the array is used to group the objects into sections; its key must either be the same as sectionNameKeyPath or the relative ordering using its key must match that using sectionNameKeyPath.

获取谓词和排序描述符


SQL存储,另一方面,编译谓词并将
描述符排序到SQL并评估数据库本身的结果。
这主要是为了提高性能,但这意味着评估
发生在非Cocoa环境中,因此依赖Cocoa的排序描述符(或
谓词)无法工作。支持的排序
选择器是...

此外,您无法使用SQLite存储对瞬态属性进行排序。

这意味着无法创建纯粹基于瞬态属性的部分。您需要一个持久属性来创建节的排序。

This means that you cannot create sections purely on transient attributes. You need a persistent attribute that creates the ordering for the sections.

更新:瞬态属性的典型用法为 sectionNameKeyPath 是:您的对象具有timeStamp属性,并且您希望将对象分组为每月一个部分的部分(请参阅 DateSectionTitles 来自iOS Developer Library的示例代码)。在这种情况下,你有

UPDATE: A typical use of a transient attribute as sectionNameKeyPath is: Your objects have a "timeStamp" attribute, and you want to group the objects into sections with one section per month (see the DateSectionTitles sample code from the iOS Developer Library). In this case you have


  • 持久属性timeStamp,

  • 使用timeStamp作为获取请求的第一个排序描述符,

  • 一个瞬态属性sectionIdentifier,用作 sectionNameKeyPath 。 sectionIdentifier从timeStamp计算并返回表示时间戳的年份和月份的字符串,例如, 2013-01。

  • a persistent attribute "timeStamp",
  • use "timeStamp" as first sort descriptor for the fetch request,
  • a transient attribute "sectionIdentifier" which is used as sectionNameKeyPath. "sectionIdentifier" is calculated from "timeStamp" and returns a string representing the year and the month of the timestamp, e.g. "2013-01".

FRC做的第一件事就是排序所有提取的对象根据timeStamp属性。然后根据sectionIdentifier属性将对象分组分段。

The first thing the FRC does is to sort all fetched objects according to the "timeStamp" attribute. Then the objects are grouped into sections according to the "sectionIdentifier" attribute.

因此,对于FRC将对象分组为 >确实需要持久属性。最简单的解决方案是向您的实体添加持久属性sectionNumber,并将sectionNameKeyPath用于第一个排序描述符。

So for a FRC to group the objects into sections you really need a persistent attribute. The easiest solution would be to add a persistent attribute "sectionNumber" to your entity, and use that for "sectionNameKeyPath" and for the first sort descriptor.

这篇关于使用NSFetchedResultsController动态创建节的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆