Coredata PerformBackgroundTask 无法在主上下文中获取更新

问题描述 投票:0回答:1

我正在尝试使用后台上下文来更新 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
不能按预期工作。正如我设置的那样,后台上下文应该与主上下文位于同一个协调器中,也就是说,更改应该自动合并到主上下文。我是不是错过了什么?
谢谢!
    

很少的东西...

ios swift core-data
1个回答
0
投票
删除

persistentContainer.viewContext.automaticallyMergesChangesFromParent = true

- 您已经在新的后台上下文线程中 - 没有必要。
  1. 没有任何内容更新
    viewContext
    对象。这可能是一个错误,但它不应该自动更新。
  2. 因此,要么使用 
    NSFetchedResultsController
  3. 来更新
performAndWait

要么(更快更好的测试方法)在保存完成后 - 移回主线程并重新获取对象。 类似这样的:

tim

© www.soinside.com 2019 - 2024. All rights reserved.