В настоящее время я работаю с SwiftUI
и CoreData
.
Ситуация: у меня есть User Detail View
с Delete Button
. При нажатии основная запись данных пользователя удаляется, а навигация приложения возвращается к корневому представлению навигации, которое представляет собой список всех пользователей.
Проблема: каждый раз, когда нажимается Delete Button
, приложение вылетает со следующим Error Message
:
*** Завершение работы приложения из-за необработанного исключения «NSInvalidArgumentException», причина: «-[User timeCreated]: нераспознанный селектор отправлен экземпляру 0x2802ffa40»
Моя догадка: я думаю, проблема как-то связана с тем фактом, что я использую @ObservedObject Property Wrapper
вместо User Object
(см. код ниже). Это также обновление при удалении, что, очевидно, вызывает некоторые проблемы.
import SwiftUI
struct UserView: View {
@FetchRequest(sortDescriptors: [NSSortDescriptor(keyPath: \User, ascending: false)], animation: .default) private var users: FetchedResults<User>
var body: some View {
NavigationView {
List {
ForEach(users) { user in
NavigationLink(destination: UserDetailView(user: user)) {
Text(user.name)
}
}
}
}
}
}
struct UserDetailView: View {
@Environment(\.managedObjectContext) var context
@Environment(\.presentationMode) var mode: Binding<PresentationMode>
@ObservedObject var user: User
var body: some View {
Button(action: { deleteUser() }) {
Text("Delete")
}
}
private func deleteUser() {
context.delete(user)
do {
try context.save()
// Navigate Back to List View
self.mode.wrappedValue.dismiss()
} catch let error as NSError {
print("Error deleting Item from Core Data: \(error), \(error.userInfo)")
}
}
}
Вопрос: Как я могу удалить пользователя и вернуться к представлению корневого списка без сбоя приложения? (Примечание: очевидно, что самым простым решением было бы сделать пользователя обычным свойством, однако мне нужно автоматическое поведение обновления, поскольку есть также представление обновления пользователя, которое может изменить часть контента)
Спасибо за вашу помощь.
Я не уверен, что проблема в предоставленном коде... но попробуйте следующее (не проверено - просто идея - отложить удаление):
private func deleteUser() {
mode.wrappedValue.dismiss()
DispatchQueue.main.async {
context.delete(user)
do {
try context.save()
} catch let error as NSError {
print("Error deleting User from Core Data: \(error), \(error.userInfo)")
}
}
}
Ну... тогда думаю причина не в этом коде. Не могли бы вы дать доступ к проекту или подготовить небольшое воспроизводимое демо?
Если это поможет, я могу это сделать. Однако не может ли ошибка заключаться в том, что в тот момент, когда вы удаляете пользователя, свойство ObservedObject пытается обновить и вызывает сбой приложения bc. соответствующая запись CoreData была удалена?
Может быть, если у вас есть прямая привязка к его свойствам где-то еще в коде.
Я обновил вопрос выше с полным кодом для этого. Можете ли вы обнаружить какую-либо ошибку?
Я только что создал простой проект CoreData и использовал ваш код вместо автоматически сгенерированного - сбой не воспроизводится. Xcode 12.1/iOS 14.1.
Давайте продолжим обсуждение в чате.
Спасибо за ваш ответ, однако приложение все еще падает. У вас есть другая идея?