Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 核心数据似乎在插入后立即删除了我的数据_Ios_Swift_Core Data - Fatal编程技术网

Ios 核心数据似乎在插入后立即删除了我的数据

Ios 核心数据似乎在插入后立即删除了我的数据,ios,swift,core-data,Ios,Swift,Core Data,我有很多数据存储在核心数据中,没有任何问题。现在我需要添加一些额外的数据。我没有为所有这些新数据创建实体,而是决定使用要存储的对象(及其所有子对象)实现NSCoding,而是将对象存储为可转换的(NSObject)。我以前做过(在Obj-c中),但由于某种原因,这次我无法让它工作 假设我有一个名为Event:NSObject的大型类,NSCoding,它包含名称、日期和一公吨附加变量。然后设想您希望能够让用户在事件开始前的给定天数内收到通知。比如,让用户“观看”事件。我想记录正在观看哪些活动,以

我有很多数据存储在核心数据中,没有任何问题。现在我需要添加一些额外的数据。我没有为所有这些新数据创建实体,而是决定使用要存储的对象(及其所有子对象)实现
NSCoding
,而是将对象存储为可转换的
(NSObject)。我以前做过(在Obj-c中),但由于某种原因,这次我无法让它工作

假设我有一个名为
Event:NSObject的大型类,NSCoding
,它包含名称、日期和一公吨附加变量。然后设想您希望能够让用户在事件开始前的给定天数内收到通知。比如,让用户“观看”事件。我想记录正在观看哪些活动,以及在发送通知之前多长时间。通过这个,我可以得到所有“关注”事件的列表,并知道他们希望在事件发生前多少天收到通知。这只是真实情况的一个糟糕的例子,请容忍我。不要考虑“通知”部分,只存储数据

我有了我的
Event
-对象,现在我在我的
CoreData
-数据库中创建了一个
WatchEvent
-实体,它有两个属性:
Event:Transformable
days:Integer
。两者都不是可选的

我的整个事件类及其所有子类现在都实现了NSCoding,所以要将其存储在数据库中,我只需将其设置为transformable属性。在这里,您可以看到我如何创建
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,并将它们打印出来。那时,一切看起来都很好。如果我单击“验证”按钮,它应该打印出相同的内容,但它已删除我的
事件
。它设法保存
-属性,但事件被删除。为什么(

无论我等待多长时间单击验证按钮,如果我几乎同时单击它们,这种情况仍然会发生

我在saveButtonClick中调用了三次
printOutAllWatchedEvents
,由于每次它都能返回一个有效的事件对象,我假设存储/NSCoding部分成功了

但是,如果我单击verify按钮(我假设以后至少会发生几个“运行循环”),则可转换的
事件
-对象已被删除

我不知道发生了什么事


如果我在插入事件后立即请求它们,但如果我以后请求它们,它为什么会设法返回我的有效事件?为什么这只会影响可转换的
对象?整数天被正确地保留在所有的
监视事件
中。而且因为我已经将
事件
标记为可选,它怎么能返回nil而不给我任何错误?当我在上下文中调用
save
时没有错误,我已经检查过了。

我发现了。它与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()
    }
}
我仍然不完全清楚为什么我会有这样的经历

编码总是成功的,因此事件存储在数据库中(即使在使用检查sqlite文件中的blob字段时它看起来是空的)。它成功地编码了,因为所有类型(Bool、Int、Double和NSObject)的函数名称都相同。它们都使用
aCoder.encode(无论如何,forKey:“随便什么”)
。但是,在解码它们时,必须选择正确的解码功能,例如
decodeBool
decodeInt32
decodeObject

正如我所说的,我以前在Objective-C中做过这件事,在那里我一点问题都没有,因为编码和解码函数都是以类型命名的(
[aDecoder DecodeBoolWorkery:@“key”];
[aCoder encodeBool:hasBeer,forKey:@“hasBeer”];
),并且在使用错误的函数时抛出编译时错误


如果我的
required init?
中有一些
fatalError(“某物”)
的话,我想我会注意到这一点,而不是在某些事情没有按计划进行时使用
return nil

既然你的问题与如何保存它有很大关系,也许可以用真正的代码代替
do/try managedObjectContext.save()否则打印出错误等。
@AlecO您是对的。现在添加。它不会打印出保存时的任何错误。首先,在数据库中检查存储在存储协调器(SQL)中的数据是否真实文件,这可能是因为您存储和获取的上下文不同?检查此项我不知道我在寻找什么。我下载了一个工具来检查实际的SQLite文件,我看到了所有的WatchEvent对象,
event
字段为空。我想这是因为它被删除了,因为我确实返回了它在我上面的代码中,如果我立即查询它,但它可能永远不会被存储,而我查询它时收到的是某种缓存?@iraniyaneynesh您提供的链接显示了与我的问题完全相反的文字。一个最初看不到存储的对象,但后来得到的对象。我可以先看到它们,但永远不会再看到它们。Will inves蒂盖特。