iOS (Swift):使用关系获取核心数据
Posted
技术标签:
【中文标题】iOS (Swift):使用关系获取核心数据【英文标题】:iOS (Swift): Core data fetching with relationships 【发布时间】:2018-06-01 15:24:31 【问题描述】:如果我有一个Person
实体和一个Book
实体,其中Person
可以有许多Book
s。
final class Person: NSManagedObject
@NSManaged public fileprivate(set) var name: String
@NSManaged public fileprivate(set) var books: Set<Book>
final class Book: NSManagedObject
@NSManaged public fileprivate(set) var name: String
@NSManaged public fileprivate(set) var person: Person
static func add(bookNamed name: String, to person: Person)
guard let context = person.managedObjectContext else fatalError("Can not obtain managed object Context")
let book = NSEntityDescription.insertNewObject(forEntityName: "Book", into: context) as Book
book.name = name
book.person = person
在一些UIViewController
中,我再添加几个Book
s到Person
:
let alex = NSEntityDescription.insertNewObjectForEntityForName("Person", inManagedObjectContext: context) as Person
Alex.name = "Alex"
Book.add("first book", to: alex)
Book.add("second book", to: alex)
Book.add("third book", to: alex)
然后是几个Book
s 到另一个Person
let john = NSEntityDescription.insertNewObjectForEntityForName("Person", inManagedObjectContext: context) as Person
john.name = "John"
Book.add("another first book", to: john)
Book.add("another second book", to: john)
然后我重新加载我的应用程序并使用获取请求来获取表格视图中的所有人(即alex
和john
)。然后我点击alex
,这会将我带到另一个视图控制器,它有一个Person
的实例,我将其分配为alex
,以便我可以查看与该实例关联的书籍。
问题即使我有 1000 个,Book
s 是否全部加载到内存中?或者,如果我想全部显示它们,是否需要执行另一次获取以获取属于 alex
的 Book
s?我只是想弄清楚两个实体之间的关系发生了什么,因为它最近让我有点困惑。
感谢您的帮助。
【问题讨论】:
【参考方案1】:CoreData
使用代理对象模型。当您执行获取请求时,它会透明地创建所有可直接访问的对象,作为代理。由于它们是代理而不是完整对象,因此它们实际上并没有在创建时从数据库中加载,而是会在需要时从数据库中加载(当实际引用属性时)同样,它们可以随时卸载如果它们未经修改和未使用。
在这种情况下,这意味着您的 fetch 请求将为每个 Person
创建卸载的代理。当您在第一个表视图中显示人员姓名时,该人员的数据将被加载(并缓存)在代理对象中。那时,该人引用的每本书的代理将被创建为一个空的代理对象。当您随后选择图书并显示图书的详细信息时,将从数据库中获取(缓存)实际图书数据。
注意:所有这些都非常依赖于实际使用的数据存储,并且仅适用于允许部分加载的存储,例如 sqlite。如果使用 XML 或 plist 存储,整个对象图将被实例化并加载,没有空代理。
【讨论】:
感谢您的回答 - 澄清了事情。以上是关于iOS (Swift):使用关系获取核心数据的主要内容,如果未能解决你的问题,请参考以下文章