Основные данные, кажется, удаляют мои данные сразу после вставки - PullRequest
0 голосов
/ 23 мая 2018

Я храню много данных в Core Data без каких-либо проблем.Теперь мне нужно добавить некоторые дополнительные данные.Вместо того чтобы создавать сущность для всех этих новых данных, я решил использовать тот факт, что сохраняемый объект (и все его дочерние элементы) реализуют NSCoding, а скорее сохраняют объект как Transformable (NSObject).Я делал это раньше (в Obj-c), но по какой-то причине я не могу заставить его работать на этот раз.

Допустим, у меня есть огромный класс с именем Event:NSObject,NSCoding, который содержит имя, дату,и метрическая тонна дополнительных переменных.Затем представьте, что вы хотите, чтобы пользователь мог получать уведомления за заданное количество дней до начала мероприятия.Мол, пусть пользователь «смотрит» событие.Я хочу отслеживать, какие события отслеживаются и как долго, прежде чем я должен отправить уведомление.Благодаря этому я могу получить список всех «наблюдаемых» событий и узнать, за сколько дней до события им нужно уведомление.Это просто плохой пример реальной ситуации, просто терпите меня.Не думайте о части «уведомление», просто храните данные.

У меня есть Event -объект, теперь я создал объект WatchEvent в моей базе данных CoreData, которая имеетдва атрибута: event:Transformable и days:Integer.Ни один из них не является обязательным.

Весь мой Event-класс и все его дочерние элементы теперь реализуют NSCoding, поэтому, чтобы сохранить это в базе данных, я просто установил его в преобразовываемый атрибут.Здесь вы можете увидеть, как я создаю WatchEvent -объект и помещаю его в базу данных, а также функцию для получения всех WatchEvents из БД и функцию для распечатки содержимого каждого WatchEvent.

func storeWatchEvent(someEvent:Event, numberOfDays:Int){
    let watchEvent = WatchEvent(entity: NSEntityDescription.entity(forEntityName: "WatchEvent", in: managedObjectContext)!, insertInto: managedObjectContext)
    watchEvent.days = numberOfDays //e.g 3
    watchEvent.event = someEvent
    saveContext()
}

func saveContext(){
    if managedObjectContext.hasChanges {
        do {
            try managedObjectContext.save()
        } catch {
            let nserror = error as NSError
            NSLog("Unresolved error \(nserror), \(nserror.userInfo)")
        }
    }
}

func getWatchedEvents()->[WatchEvent]?{
    return managedObjectContext.fetch(WatchEvent.fetchRequest())
}

func printOutAllWatchedEvents(){
    if let watchedEvents = getWatchedEvents(){
        watchedEvents.foreach{ (w) in
            print("numberOfDays: ", w.days)
            print("event: ", w.event)
        }
    }
}

func saveButtonClicked(){
    storeWatchEvent(someEvent, numberOfDays:3)

    // For testing, attempt to get all my events immediately, several times
    printOutAllWatchedEvents() //Prints out `numberOfDays: 3` and a valid `event` correctly
    printOutAllWatchedEvents() //Prints out `numberOfDays: 3` and a valid `event` correctly
    printOutAllWatchedEvents() //Prints out `numberOfDays: 3` and a valid `event` correctly
}

func verifyButtonClicked(){
    printOutAllWatchedEvents() //Prints out `numberOfDays: 3` and `nil` for event.
}

Допустим, у меня есть две кнопки.Один «Сохранить», а другой «Проверить».Если я нажимаю «Сохранить», я сохраняю действительные объекты и, как вы можете видеть в коде, я немедленно запрашиваю в базе данных все сохраненные WatchEvents и распечатываю их.В это время все выглядит хорошо.Если я нажму кнопку «проверить», она должна была распечатать то же самое, но она удалила мой event.Ему удается сохранить days -атрибут, но событие удаляется.Почему?: (

Не имеет значения, как долго я жду нажатия кнопки проверки. Если я нажимаю их почти одновременно, это все равно происходит.

Я звоню printOutAllWatchedEvents в saveButtonClick три раза, и, поскольку ему удается каждый раз возвращать действительный объект события, я предполагаю, что сохранение / NSCoding-часть этого прошло успешно?

Но если я нажму кнопку проверки,что, я предполагаю, произойдет, по крайней мере, через несколько «циклов выполнения», трансформируемый event -объект был удален ..

Я понятия не имею, что происходит.вернуть мои действительные события, если я запрашиваю их сразу после их вставки, но не если я запрашиваю их позже? Почему это влияет только на объект transformable? Целое число days правильно сохраняется для всех WatchEvent с.Я пометил event как , а не необязательно, как он может вернуть ноль и никогда не давать мне ошибок? Нет ошибок при вызове save в контексте, я проверил.

1 Ответ

0 голосов
/ 23 мая 2018

Я понял это .. Это не имеет ничего общего с CoreData, правда.Это была ошибочная реализация NSCoding.Я никогда не получал никаких ошибок, поэтому было трудно разобраться, особенно с таким большим количеством переменных, но проблема была в основном в следующем:

class Event:NSObject,NSCoding{

    let hasBeer:Bool

    func encode(with aCoder: NSCoder) {
        aCoder.encode(hasBeer, forKey: "hasBeer")
    }
    required init?(coder aDecoder: NSCoder) {
        //This line:
        self.hasBeer = aDecoder.decodeObject(forKey: "hasBeer") as? Bool ?? false
        //Should be like this:
        self.hasBeer = aDecoder.decodeBool(forKey: "hasBeer")
        //Because it is a primitive type Bool, and not an Object of any kind.
        super.init()
    }
}

Я до сих пор не совсем уверен, почему я испытал этокак это, хотя ..

Кодирование всегда выполнялось успешно, поэтому Событие было сохранено в базе данных (даже если оно выглядело пустым при проверке blob-поля в sqlite-файле с использованием * Liya 1010 *).Кодирование успешно завершено, поскольку функции названы одинаково для всех типов (Bool, Int, Double и NSObject).Все они работают с aCoder.encode(whatever, forKey: "whatever").Однако при их DE-кодировании вы должны выбрать правильную функцию декодирования, например, decodeBool, decodeInt32, decodeObject и т. Д.

Как я уже говорил, я делал это в прошлом, в Objective-C, где у меня не было никаких проблем, потому что функции кодирования и декодирования были названы для типа ([aDecoder decodeBoolForKey:@"key"]; и [aCoder encodeBool:hasBeer, forKey:@"hasBeer"];), и выдавали ошибки времени компиляции при использовании неправильной.

Полагаю, я бы понял это, если бы у меня было fatalError("something") в моем required init? вместо простого использования return nil, когда что-то пошло не так, как планировалось.

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