奇怪的核心数据行为(重复条目)
Strange Core Data behaviour (duplicating entries)
我有一个小游戏,我想存储一个代表用户解锁的最后一个级别的数字。
所以我有一个 class 来保存和加载核心数据。
首先我声明处理核心数据所需的对象(我从教程中获取它们)
override init() {
super.init()
appDelegate = UIApplication.sharedApplication().delegate as AppDelegate
managedContext = appDelegate.managedObjectContext!
entity = NSEntityDescription.entityForName("Data", inManagedObjectContext: managedContext)
data = NSManagedObject(entity: entity!, insertIntoManagedObjectContext: managedContext)
这是我的保存方式
func saveData() {
data.setValue(lastUnlockedLevel, forKey: "lastUnlockedLevel")
var error: NSError?
if !managedContext.save(&error) {
println("Could not save \(error), \(error?.userInfo)")
}
}
这是我的加载方法
func loadData() {
let fetchRequest = NSFetchRequest(entityName: "Data")
fetchRequest.returnsObjectsAsFaults = false
var error: NSError?
let fetchedResults = managedContext.executeFetchRequest(fetchRequest, error: &error) as [NSManagedObject]?
if let results = fetchedResults {
if results.count == 0 {
createInitialData()
} else if results.count > 0 {
lastUnlockedLevel = results[0].valueForKey("lastUnlockedLevel") as Int
}
} else {
println("Could not fetch \(error), \(error?.userInfo)")
}
}
我是新手,可能理解有误。
加载我的应用程序后 - 我检查是否存在核心数据。如果不是 - 我将 lastUnlockedLevel 变量设置为 1。当我解锁一个级别时,我增加我的 var 并将其保存到应用程序存储。
当我再次加载应用程序时,我跟踪我的结果数组并看到如下内容:
[<NSManagedObject: 0x14602790> (entity: Data; id: 0x14602650 <x-coredata://B994407F-5A33-446F-BB13-758F1190A45A/Data/p1> ; data: {
lastUnlockedLevel = 2;}),
<NSManagedObject: 0x14607770> (entity: Data; id: 0x14602670 <x-coredata://B994407F-5A33-446F-BB13-758F1190A45A/Data/p3> ; data: {
lastUnlockedLevel = 0;}),
<NSManagedObject: 0x1460ae20> (entity: Data; id: 0x1460ae50 <x-coredata:///Data/t3EEBBE5F-DF13-4C34-AE59-96AEE72DF0A52> ; data: {
lastUnlockedLevel = 0;}),
<NSManagedObject: 0x14607740> (entity: Data; id: 0x14602660 <x-coredata://B994407F-5A33-446F-BB13-758F1190A45A/Data/p2> ; data: {
lastUnlockedLevel = 0;
同一数据库字段的多个条目。我明白应该只有一个条目?更令人困惑的是,当我的 lastUnlockedLevel 为 0 时,我从不保存数据。
我做错了什么?
})]
我鼓励您使用更简单的解决方案。
使用NSUserDefaults,这个class就是专门为这种用途引入的
在你代码的全局部分,你可以添加这个:
private let lastUnlockedLevelKey = "LastUnlockedLevel"
public var lastUnlockedLevel: Int {
get {
let userDefaults = NSUserDefaults.standardUserDefaults()
let theLevel = userDefaults.integerForKey(lastUnlockedLevelKey)
return theLevel > 0 ? theLevel : 1
}
set {
let userDefaults = NSUserDefaults.standardUserDefaults()
userDefaults.setInteger(newValue, forKey: lastUnlockedLevelKey)
userDefaults.synchronize()
}
}
例如,您可以将其放在 AppDelegate.swift 的开头(在 class 定义之外)。
比起在您编写代码的任何地方,您都可以将 lastUnlockedLevel
用作普通变量。每次设置它都会保存在标准用户默认值中。
我有一个小游戏,我想存储一个代表用户解锁的最后一个级别的数字。 所以我有一个 class 来保存和加载核心数据。
首先我声明处理核心数据所需的对象(我从教程中获取它们)
override init() {
super.init()
appDelegate = UIApplication.sharedApplication().delegate as AppDelegate
managedContext = appDelegate.managedObjectContext!
entity = NSEntityDescription.entityForName("Data", inManagedObjectContext: managedContext)
data = NSManagedObject(entity: entity!, insertIntoManagedObjectContext: managedContext)
这是我的保存方式
func saveData() {
data.setValue(lastUnlockedLevel, forKey: "lastUnlockedLevel")
var error: NSError?
if !managedContext.save(&error) {
println("Could not save \(error), \(error?.userInfo)")
}
}
这是我的加载方法
func loadData() {
let fetchRequest = NSFetchRequest(entityName: "Data")
fetchRequest.returnsObjectsAsFaults = false
var error: NSError?
let fetchedResults = managedContext.executeFetchRequest(fetchRequest, error: &error) as [NSManagedObject]?
if let results = fetchedResults {
if results.count == 0 {
createInitialData()
} else if results.count > 0 {
lastUnlockedLevel = results[0].valueForKey("lastUnlockedLevel") as Int
}
} else {
println("Could not fetch \(error), \(error?.userInfo)")
}
}
我是新手,可能理解有误。 加载我的应用程序后 - 我检查是否存在核心数据。如果不是 - 我将 lastUnlockedLevel 变量设置为 1。当我解锁一个级别时,我增加我的 var 并将其保存到应用程序存储。
当我再次加载应用程序时,我跟踪我的结果数组并看到如下内容:
[<NSManagedObject: 0x14602790> (entity: Data; id: 0x14602650 <x-coredata://B994407F-5A33-446F-BB13-758F1190A45A/Data/p1> ; data: {
lastUnlockedLevel = 2;}),
<NSManagedObject: 0x14607770> (entity: Data; id: 0x14602670 <x-coredata://B994407F-5A33-446F-BB13-758F1190A45A/Data/p3> ; data: {
lastUnlockedLevel = 0;}),
<NSManagedObject: 0x1460ae20> (entity: Data; id: 0x1460ae50 <x-coredata:///Data/t3EEBBE5F-DF13-4C34-AE59-96AEE72DF0A52> ; data: {
lastUnlockedLevel = 0;}),
<NSManagedObject: 0x14607740> (entity: Data; id: 0x14602660 <x-coredata://B994407F-5A33-446F-BB13-758F1190A45A/Data/p2> ; data: {
lastUnlockedLevel = 0;
同一数据库字段的多个条目。我明白应该只有一个条目?更令人困惑的是,当我的 lastUnlockedLevel 为 0 时,我从不保存数据。 我做错了什么? })]
我鼓励您使用更简单的解决方案。 使用NSUserDefaults,这个class就是专门为这种用途引入的
在你代码的全局部分,你可以添加这个:
private let lastUnlockedLevelKey = "LastUnlockedLevel"
public var lastUnlockedLevel: Int {
get {
let userDefaults = NSUserDefaults.standardUserDefaults()
let theLevel = userDefaults.integerForKey(lastUnlockedLevelKey)
return theLevel > 0 ? theLevel : 1
}
set {
let userDefaults = NSUserDefaults.standardUserDefaults()
userDefaults.setInteger(newValue, forKey: lastUnlockedLevelKey)
userDefaults.synchronize()
}
}
例如,您可以将其放在 AppDelegate.swift 的开头(在 class 定义之外)。
比起在您编写代码的任何地方,您都可以将 lastUnlockedLevel
用作普通变量。每次设置它都会保存在标准用户默认值中。