我目前正在通过Apple的Core Data Programming Guide阅读并遇到将瞬态属性合并更改(Managed Objects and References的最后一段)。它与awakeFromFetch()
和refresh(_:mergeChanges:)
一起处理Core Data的瞬态属性。
不幸的是,我无法重现所描述的行为。考虑到某些领域的指南似乎不足,我想知道该段的内容是否正确。
我使用Single View Application
模板并选中Use Core Data
来验证断言:
AppDelegate.swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// check properties and fire faults
func check(_ person: Person) {
print(" check: \(person.firstName ?? "nil") | \(person.lastName ?? "nil") | \(person.fullName ?? "nil")\n")
}
// clear persistent store
let viewContext = persistentContainer.viewContext
let fetchRequest: NSFetchRequest<NSFetchRequestResult> = Person.fetchRequest()
let batchDeleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
try! persistentContainer.persistentStoreCoordinator.execute(batchDeleteRequest, with: viewContext)
// insert person
print("# persistent store: insert\n")
weak var person = Person(context: viewContext)
person!.firstName = "Sarit"
person!.lastName = "Smith"
check(person!)
try! viewContext.save()
// create background contexts
let context1 = persistentContainer.newBackgroundContext()
let context2 = persistentContainer.newBackgroundContext()
// run test
context2.performAndWait {
print("# context2: fetch\n")
let fetchRequest: NSFetchRequest<Person> = Person.fetchRequest()
let person = try! context2.fetch(fetchRequest).first!
check(person)
context1.performAndWait {
print("# context1: fetch\n")
let fetchRequest: NSFetchRequest<Person> = Person.fetchRequest()
let person = try! context1.fetch(fetchRequest).first!
check(person)
print("# context1: modify\n")
person.firstName = "Fiona"
check(person)
try! context1.save()
}
print("# persistent store: check\n")
viewContext.performAndWait {
let fetchRequest: NSFetchRequest<Person> = Person.fetchRequest()
let person = try! viewContext.fetch(fetchRequest).first!
check(person)
}
print("# context2: modify\n")
person.lastName = "Jones"
check(person)
print("# context2: refresh\n")
context2.refresh(person, mergeChanges: true)
check(person)
}
return true
}
人员+ CoreDataClass.swift
override public func awakeFromFetch() {
super.awakeFromFetch()
print("-> awakeFromFetch\n")
print(" before: \(firstName ?? "nil") | \(lastName ?? "nil") | \(fullName ?? "nil")")
fullName = "\(firstName!) \(lastName!)"
print(" after: \(firstName ?? "nil") | \(lastName ?? "nil") | \(fullName ?? "nil")\n")
}
输出
# persistent store: insert
check: Sarit | Smith | nil
# context2: fetch
-> awakeFromFetch
before: Sarit | Smith | nil
after: Sarit | Smith | Sarit Smith
check: Sarit | Smith | Sarit Smith
# context1: fetch
-> awakeFromFetch
before: Sarit | Smith | nil
after: Sarit | Smith | Sarit Smith
check: Sarit | Smith | Sarit Smith
# context1: modify
check: Fiona | Smith | Sarit Smith (1.)
// (1.) [...] which causes the cached fullName to be updated to "Fiona Smith"[...]
# persistent store: check
-> awakeFromFetch
before: Fiona | Smith | nil
after: Fiona | Smith | Fiona Smith
check: Fiona | Smith | Fiona Smith
# context2: modify
check: Sarit | Jones | Sarit Smith (1.)
// (1.) [...] which causes the cached fullName to be updated to "Sarit Jones".
# context2: refresh
-> awakeFromFetch
before: Fiona | Smith | nil
after: Fiona | Smith | Fiona Smith
-> awakeFromFetch
before: Fiona | Jones | Sarit Smith (2.)
after: Fiona | Jones | Fiona Jones (3.)
check: Fiona | Jones | Fiona Jones (3.)
// The transient value, fullName, was also changed prior to the refresh.
// (2.) After the refresh, its value is restored to "Sarit Jones".
// (3.) However, to be correct, it should be "Fiona Jones".
将生成的输出与指南中的摘录进行比较后的结果:
awakeFromFetch()
,正确更新瞬态值。我忽略了什么吗?我的代码是问题吗?该段落不足吗?
非常感谢提前。