Основные данные создает новый объект при обновлении старого - PullRequest
0 голосов
/ 28 мая 2019

Начнем с того, что я не верю, что это дубликат: Обновление значения объекта в основных данных также создает новый объект (Это в Obj-C, и они вызывали insertNewObject каждый раз, когда ониsegued.)

Справочная информация: я узнал, как использовать CoreData из книги Рэя Вендерлиха, и ссылался на нее при написании этого кода.Я свернул свой собственный стек, как описано в Главе 3, если у вас есть книга.При необходимости я могу показать код для этого.

Очередь - это объект, который я пытаюсь обновить.

У него есть 1 свойство: name - String

И от 1 до-много отношения: задачи: Задача enter image description here enter image description here enter image description here Моя логика CoreData находится в структуре, которая содержит managedContext.

У меня есть базовая функция поиска / создания для создания объекта Queue.Это работает.Он создает 1 и только 1 объект.

func findOrCreateMainQueue() -> Queue? {
    let queue = Queue(context: managedContext)
    queue.name = "Queue32"

    let queueFetch: NSFetchRequest<Queue> = Queue.fetchRequest()
    queueFetch.predicate = NSPredicate(format: "%K == %@", #keyPath(Queue.name), "Queue32" as CVarArg)
    do {
        let results = try managedContext.fetch(queueFetch)
        print(results.count)

        if results.count > 0 {
            return results.first!
        } else {
            try managedContext.save()
        }

    } catch let error as NSError {
        print("Fetch error: \(error) description: \(error.userInfo)")
    }

    return nil
}

(Как вы можете видеть по номеру суффикса queue.name, я пробовал много разных вещей.)

Я пробовал примерновсе, что я могу придумать:

Этот код в основном копируется / вставляется из: Как обновить запись CoreData, которая уже была сохранена в Swift?

func addTaskToMainQueue2(task: Task) {
    let queueFetch: NSFetchRequest<Queue> = Queue.fetchRequest()
    queueFetch.predicate = NSPredicate(format: "%K == %@", #keyPath(Queue.name), "Queue32" as CVarArg)
    do {
        let results = try managedContext.fetch(queueFetch)
        print(results.count)

        if results.count > 0 {

            var tasks = results[0].tasks?.mutableCopy() as? NSMutableOrderedSet
            tasks?.add(task)
            results[0].setValue(tasks, forKey: "tasks")
        }

    } catch let error as NSError {
        print("Fetch error: \(error) description: \(error.userInfo)")
    }

        do {
            try managedContext.save()
        } catch let error as NSError {
            print("Save error: \(error),description: \(error.localizedDescription)")
        }


}

Что вызывает создание второго объекта Queue с именем "Queue32".

Вот еще одна вещь, которую я попробовал:

func addTaskToMainQueue(task: Task) {
    if var queue = findOrCreateMainQueue() {
        var tasks = queue.tasks?.mutableCopy() as? NSMutableOrderedSet
        tasks?.add(task)
        queue.tasks = tasks
        do {
            try managedContext.save()
        } catch let error as NSError {
            print("Save error: \(error),description: \(error.localizedDescription)")
        }

    }
}

Ради места не буду добавлять коддля других вещей, которые я пробовал.

  • Я пытался использовать функцию поиска / создания и обновления в этом методе.
  • Я пытался сохранить очередь как локальный объект и передать ее в функцию addTask, которая также вызывает дублирование.
  • Также не имеет значения, передам ли я задачу или создаюодин из них в функции addTask.

Я начинаю верить, что моя проблема заключается в том, что что-то в моем файле dataModel вызывает эту проблему, поскольку я попробовал несколько учебных пособий «Как обновить объект Core Data» в Интернете иЯ получаю один и тот же результат каждый раз.

awakeFromInsert () вызывается всякий раз, когда я пытаюсь обновить объект.Не уверен, должно ли это происходить.

В других местах моего приложения обновление работает.Например, если я добавлю подзадачу в задачу.Работает нормально.Однако, если я хочу изменить имя другого объекта с именем Project, объект дублируется.(У проекта есть атрибут id, который извлекается, затем атрибут имени изменяется.)

Заранее спасибо.Я вырывал свои волосы часами.

1 Ответ

1 голос
/ 28 мая 2019

Я признаю, что не прочитал весь ваш код, но если вы создаете новый управляемый объект, подобный этому

let queue = Queue(context: managedContext)

, затем он будет добавлен к managedContext и в какой-то момент будет сохранен на диск. Итак, этот код

if results.count > 0 {
    return results.first!
} else {
    try managedContext.save()
}

не имеет отношения к объекту queue, созданному ранее, потому что он будет сохранен, даже если results.count равен> 0, хотя и в более поздней точке. Таким образом, это означает, что вам нужно будет удалить queue, когда выборка будет успешной, что кажется ненужным, лучше подождать с ее созданием

if results.count > 0 {
    return results.first!
} else {
    let queue = Queue(context: managedContext)
    queue.name = "Queue32"
    try managedContext.save()
}

Не по теме, но я вижу, вы возвращаете ноль, если новый объект был создан, а не извлечен, это предназначено?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...