Удаление элемента CoreData, который также является @ObservedObject в DetailView, вызывая сбой приложения в Swift 5

В настоящее время я работаю с 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)")
        }
    }
}

Вопрос: Как я могу удалить пользователя и вернуться к представлению корневого списка без сбоя приложения? (Примечание: очевидно, что самым простым решением было бы сделать пользователя обычным свойством, однако мне нужно автоматическое поведение обновления, поскольку есть также представление обновления пользователя, которое может изменить часть контента)

Спасибо за вашу помощь.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
373
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я не уверен, что проблема в предоставленном коде... но попробуйте следующее (не проверено - просто идея - отложить удаление):

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)")
      }
   }
}

Спасибо за ваш ответ, однако приложение все еще падает. У вас есть другая идея?

christophriepe 16.12.2020 19:16

Ну... тогда думаю причина не в этом коде. Не могли бы вы дать доступ к проекту или подготовить небольшое воспроизводимое демо?

Asperi 16.12.2020 19:21

Если это поможет, я могу это сделать. Однако не может ли ошибка заключаться в том, что в тот момент, когда вы удаляете пользователя, свойство ObservedObject пытается обновить и вызывает сбой приложения bc. соответствующая запись CoreData была удалена?

christophriepe 16.12.2020 19:23

Может быть, если у вас есть прямая привязка к его свойствам где-то еще в коде.

Asperi 16.12.2020 19:25

Я обновил вопрос выше с полным кодом для этого. Можете ли вы обнаружить какую-либо ошибку?

christophriepe 16.12.2020 19:38

Я только что создал простой проект CoreData и использовал ваш код вместо автоматически сгенерированного - сбой не воспроизводится. Xcode 12.1/iOS 14.1.

Asperi 16.12.2020 20:02

Давайте продолжим обсуждение в чате.

christophriepe 16.12.2020 20:08

Другие вопросы по теме