【发布时间】:2021-07-25 06:59:49
【问题描述】:
我是 Realm 的新手,我希望它能在 CoreData 中做一些简单的事情。首先,我将解释它是如何与 CoreData 一起工作的,然后我会问是否或如何使用 Realm 来完成它。
TL;DR:我希望 Realm 的功能类似于您使用 NSFetchedResultsController 获得的功能,特别是它如何轻松管理表格视图部分。如果您知道答案,您可能可以跳过下面的详细信息。
这是场景。假设我们有一个这样的数据模型:
┌────────────────┐
│Category │
│ - name │ ┌────────────────┐
│ - description │┼─────┐ │Item │
│ - items │ │ ┌│ - name │
│ - dateCreated │ └────○┼│ - description │
└────────────────┘ └│ - category │
│ - dateCreated │
└────────────────┘
一个Category 可以有多个Items。一个Item 有一个Category。
假设我们在表格视图中显示了一些Items。表格视图由Category 划分。所以它看起来像这样:
┌──────────────┐
│Camping │
│ Axe │
│ Firestartor │
│Clothing │
│ Bug shirt │
│ Long pants │
│ │
└──────────────┘
是的,有一个错字。我们会解决的。 Camping 是Category,显示在部分标题中。它的Items 是该部分中的行。与 Clothing 相同,它是 Category,位于部分标题中,其 Items 是该部分中的行。
使用 CoreData,这很容易通过 NSFetchedResultsController 来实现,如下所示:
let fr = NSFetchRequest<Item> = NSFetchRequest(…)
fr.predicate = …
fr.sortDescriptors = …
let frc = NSFetchedResultsController(fetchRequest: fr, managedObjectContext: moc, sectionNameKeyPath: “category.name”, cacheName: nil)
获取请求 fr 很像 Realm 查询。它指定实体以及谓词和排序描述符。在这种情况下,假设排序描述符是按照类别名称中的项目名称进行排序。
但是对于部分,关键是为sectionNameKeyPath 参数提供一个值。该值与您在获取请求中指定的实体相关。所以在这种情况下category.name 是相对于Item 的。 Item 有一个 Category 和一个 Category 有一个名字。所以这些部分将是Category 名称。
现在,在cellForRowAt 我只是这样做
let item = frc.object(at: indexPath)
cell.textField.text = item.name
自从我们提供了sectionNameKeyPath,获取结果控制器已经完成了所有的工作,并且已经对部分进行了分类并且知道哪些Items 在哪些部分中。这就是使用NSFetchedResultsController 加载分段表视图的全部内容。
此外,就像 Realm 集合观察者一样,NSFetchedResultsController 监听变化。在这种情况下,它正在侦听对 Items 的更改。假设用户点击选项卡栏上的另一个选项卡并转到应用程序的其他位置,注意到“firestartor”的拼写错误并修复它。另一个视图控制器上的frc 将注意到该更改并调用其委托方法,它将该行的 indexPath 传递给我,我可以只更新单元格。我不需要做任何处理来找出索引路径,它只是将正确的索引路径传递给我。
问题:
- Realm 是否有类似
NSFetchedResultsController的机制,可以轻松处理部分,还是部分是否喜欢完全取决于开发人员?
RealmCollectionChange 的文档说...
更改信息有两种格式:集合中针对每种更改类型的简单行索引数组,以及适合直接传递给 UITableView 的批量更新方法的请求部分中的索引路径数组。
- 我得到的只是行索引的简单数组。你如何获得其他格式?具有索引路径数组的那个?
【问题讨论】:
-
不确定问题是否超级清楚,一个好的答案将取决于您如何创建一个部分。例如,在您的示例中,您有带有 A、B、C... 的部分,然后用户名位于与字母匹配的部分中。如果用户的姓氏从 Smith 更改为 Jones,则该对象将传递给观察者,您可以将其从 Smith 部分中删除并将其插入 Jones 部分 - 这是文档拼写顺序的原因之一; 在集合通知处理程序中,始终按以下顺序应用更改:删除、插入、然后修改。
-
@Jay 在将 Smith 更改为 Jones 的情况下,
RealmCollectionChange对象没有提供足够的信息。它返回一个简单的行索引数组。当然,我可以只使用reloadData(),但是没有动画。我希望有办法获得新的 indexPath。 -
@Jay 我把你关于不太清楚的评论放在心上,我已经编辑了这个问题。现在我在全面描述 CoreData 可以完成的事情,然后询问 Realm 是否有类似的功能。
标签: ios swift core-data realm nsfetchedresultscontroller