Я подготовил демонстрационный проект и демонстрационное видео с проблемой.
Я хотел бы знать, как правильно использовать transaction.edit
.
В настоящее время, если вы посмотрите на мой демонстрационный проект , есть функция под названием updateCompany
, где я добавляю сотрудника в компанию:
func updateCompany(with company: Company, completion: @escaping (Result<Company, Error>) -> Void) {
CoreStore.perform(
asynchronous: { (transaction) -> Company in
let editCompany = transaction.edit(company)!
editCompany.name = company.name
if let unwrappedEmployees = company.employees {
for employee in unwrappedEmployees {
if let castedEmployee = employee as? Employee {
let editEmployee = transaction.edit(castedEmployee)!
editCompany.addToEmployees(editEmployee)
}
}
}
return editCompany
},
success: { (transactionCompany) in
guard let fetchedObject = CoreStore.fetchExisting(transactionCompany) else {
return
}
completion(.success(fetchedObject))
},
failure: { (error) in
completion(.failure(error))
})
и в этом случае все работает хорошо, все записи сохраняются правильно. Но что для меня странно, что в описании функции transaction.edit
написано, что оно "возвращает редактируемый прокси указанного NSManagedObject
или CoreStoreObject
."
Таким образом, вы, как первый пользователь этой функции, подозреваете, что на самом деле получите прокси NSManagedObject
(в моем случае это company
экземпляр выше) с уже существующим отношением ко многим сотрудникам . И как первый раз пользователь этого функционала пишет следующий код:
func updateCompany(with company: Company, completion: @escaping (Result<Company, Error>) -> Void) {
CoreStore.perform(
asynchronous: { (transaction) -> Company in
let editCompany = transaction.edit(company)!
// take a look print(editCompany.employees)
// suspect all employees are there, but they are not!
return editCompany
},
success: { (transactionCompany) in
guard let fetchedObject = CoreStore.fetchExisting(transactionCompany) else {
return
}
// WHICH IS MORE STRANGE all added employees are returned here from successful transaction
completion(.success(fetchedObject))
},
failure: { (error) in
completion(.failure(error))
})
Когда вы поняли, что что-то странное произошло, мы открываем документацию , в которой говорится:
Не обновлять экземпляр, который не был создан / извлечен из
сделка. Если у вас уже есть ссылка на объект, используйте
метод edit (...) транзакции, чтобы получить редактируемый экземпляр прокси для
этот объект
Как вы видите из моего демонстрационного проекта, я обновляю свои NSSet
из employees
, которые были извлечены из формы вне transaction
некоторое время назад, но я думаю, руководство упоминало о выполнении асинхронизации / синхронизации transaction
, которое мы используем для обновления наш NSManagedObject
Пожалуйста, исправьте меня, как правильно использовать transaction.edit
.