我正在尝试使用后台上下文来更新 NSManagedObject(User),并在主 viewContext 中获取更新。
遵循:Apple 的文档
这是代码:
func testUpdateUser() throws {
//Step 1. Create User in mainViewContext
let tim = userStore?.fetchUser(userName: "Tim")
XCTAssertNotNil(tim)
//Step 2. Update user's attribute in background context
let context = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
context.parent = persistentContainer.viewContext
let expectation = XCTestExpectation(description: "updateUser")
context.performAndWait{
do {
guard let user = try context.existingObject(with: tim!.objectID) as? User else {
return
}
user.foo = "foo"
context.performAndWait {
do {
try context.save()
} catch {
print(error)
}
}
} catch {
print(error)
}
persistentContainer.viewContext.performAndWait {
try? persistentContainer.viewContext.save()
}
expectation.fulfill()
}
//Step 3. assert it works.
wait(for: [expectation], timeout: 2.0)
XCTAssertEqual(Tim?.foo, "foo") //Passed
}
我已设置
persistentContainer.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
persistentContainer.viewContext.automaticallyMergesChangesFromParent = true
代码运行良好。
然后我想用
performBackgroundTask
来做同样的功能:
func testUpdateUserBackgroundTask() throws {
//Step 1. Create User and fetch in mainViewContext
let tim = userStore?.fetchUser(userName: "Tim")
XCTAssertNotNil(tim)
//Step 2. Update user's attribute in background context
let expectation = XCTestExpectation(description: "updateUser")
persistentContainer.performBackgroundTask({ context in
do {
guard let user = try context.existingObject(with: tim!.objectID) as? User else {
return
}
user.foo = "foo"
context.performAndWait {
do {
try context.save()
} catch {
print(error)
}
}
} catch {
print(error)
}
expectation.fulfill()
})
wait(for: [expectation], timeout: 2.0)
XCTAssertEqual(tim?.foo, "foo") // NOT PASS!
}
我不太清楚为什么
performBackgroundTask
不能按预期工作。正如我设置的那样,后台上下文应该与主上下文位于同一个协调器中,也就是说,更改应该自动合并到主上下文。我是不是错过了什么?谢谢!很少的东西...