NSUserDefaults 加载问题
NSUserDefaults Loading Issue
每当我打开我的应用程序时,它都不会加载我的数组值,因为没有调用 != nil 函数。我能做些什么吗?
代码:
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
var toDoData = NSUserDefaults.standardUserDefaults()
if (toDoData.valueForKey("TDDATA") != nil){
todos = toDoData.valueForKey("TDDATA") as! NSArray as! [TodoModel]
}
if todos.count != 0{
toDoData.setValue(todos, forKeyPath: "TDDATA")
toDoData.synchronize()
}
}
不用担心 table。它完美地填充。我只需要修复加载数据问题。
您答案中包含的代码很有帮助!
谢谢。
更新:
这是 TodoModel:
import Foundation
import UIKit
class TodoModel : NSObject, NSCoding {
var id: String
var image: String
var title: String
var desc: String
var scores: String
init (id: String, image: String, title: String, desc: String, scores: String) {
self.id = id
self.image = image
self.title = title
self.desc = desc
self.scores = scores
}
}
valueForKey
和 setValue:forKeyPath
是 KVC(键值编码)方法(阅读 here and here)。它不会帮助你 read/write 到用户默认数据库。
查看 NSUserDefaults
documentation,有许多方法可用于在默认数据库中获取和设置值。由于您使用的是数组,我们将使用:
arrayForKey
得到。
setObject:forKey
设置。 (没有特定数组setter)
编辑:在您的 viewDidAppear
中试试这个。在这里我们检查我们是否有数据,如果有,我们存储它。如果我们没有数据,则检查默认数据库是否保存了一些数据。如果是这样,请改用它。最好只从 viewDidLoad
中的默认数据库加载数据,然后保存在 viewDidAppear
中,甚至更好,添加待办事项时调用的函数。
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
let defaults = NSUserDefaults.standardUserDefaults()
if todos.count > 0 {
// Save what we have
let data = NSKeyedArchiver.archivedDataWithRootObject(todos)
defaults.setObject(data, forKey: "TDDATA")
defaults.synchronize()
print("saved \(todos.count)")
} else if let storedTodoData = defaults.dataForKey("TDDATA"),
storedTodos = NSKeyedUnarchiver.unarchiveObjectWithData(storedTodoData) as? [TodoModel] {
// There was stored data! Use it!
todos = storedTodos
print("Used \(todos.count) stored todos")
}
}
此外,我们必须在您的模型中实施 NSCoding
协议。这应该是这样的:
class TodoModel: NSObject, NSCoding {
var myInt: Int = 0
var myString: String?
var myArray: [String]?
required init?(coder aDecoder: NSCoder) {
myInt = aDecoder.decodeIntegerForKey("myInt")
myString = aDecoder.decodeObjectForKey("myString") as? String
myArray = aDecoder.decodeObjectForKey("myArray") as? [String]
}
func encodeWithCoder(aCoder: NSCoder) {
aCoder.encodeInteger(myInt, forKey: "myInt")
aCoder.encodeObject(myString, forKey: "myString")
aCoder.encodeObject(myArray, forKey: "myArray")
}
}
(当然,将 myInt、myString、myArray 等替换为您的模型可能具有的任何属性。)
每当我打开我的应用程序时,它都不会加载我的数组值,因为没有调用 != nil 函数。我能做些什么吗?
代码:
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
var toDoData = NSUserDefaults.standardUserDefaults()
if (toDoData.valueForKey("TDDATA") != nil){
todos = toDoData.valueForKey("TDDATA") as! NSArray as! [TodoModel]
}
if todos.count != 0{
toDoData.setValue(todos, forKeyPath: "TDDATA")
toDoData.synchronize()
}
}
不用担心 table。它完美地填充。我只需要修复加载数据问题。
您答案中包含的代码很有帮助!
谢谢。
更新:
这是 TodoModel:
import Foundation
import UIKit
class TodoModel : NSObject, NSCoding {
var id: String
var image: String
var title: String
var desc: String
var scores: String
init (id: String, image: String, title: String, desc: String, scores: String) {
self.id = id
self.image = image
self.title = title
self.desc = desc
self.scores = scores
}
}
valueForKey
和 setValue:forKeyPath
是 KVC(键值编码)方法(阅读 here and here)。它不会帮助你 read/write 到用户默认数据库。
查看 NSUserDefaults
documentation,有许多方法可用于在默认数据库中获取和设置值。由于您使用的是数组,我们将使用:
arrayForKey
得到。setObject:forKey
设置。 (没有特定数组setter)
编辑:在您的 viewDidAppear
中试试这个。在这里我们检查我们是否有数据,如果有,我们存储它。如果我们没有数据,则检查默认数据库是否保存了一些数据。如果是这样,请改用它。最好只从 viewDidLoad
中的默认数据库加载数据,然后保存在 viewDidAppear
中,甚至更好,添加待办事项时调用的函数。
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
let defaults = NSUserDefaults.standardUserDefaults()
if todos.count > 0 {
// Save what we have
let data = NSKeyedArchiver.archivedDataWithRootObject(todos)
defaults.setObject(data, forKey: "TDDATA")
defaults.synchronize()
print("saved \(todos.count)")
} else if let storedTodoData = defaults.dataForKey("TDDATA"),
storedTodos = NSKeyedUnarchiver.unarchiveObjectWithData(storedTodoData) as? [TodoModel] {
// There was stored data! Use it!
todos = storedTodos
print("Used \(todos.count) stored todos")
}
}
此外,我们必须在您的模型中实施 NSCoding
协议。这应该是这样的:
class TodoModel: NSObject, NSCoding {
var myInt: Int = 0
var myString: String?
var myArray: [String]?
required init?(coder aDecoder: NSCoder) {
myInt = aDecoder.decodeIntegerForKey("myInt")
myString = aDecoder.decodeObjectForKey("myString") as? String
myArray = aDecoder.decodeObjectForKey("myArray") as? [String]
}
func encodeWithCoder(aCoder: NSCoder) {
aCoder.encodeInteger(myInt, forKey: "myInt")
aCoder.encodeObject(myString, forKey: "myString")
aCoder.encodeObject(myArray, forKey: "myArray")
}
}
(当然,将 myInt、myString、myArray 等替换为您的模型可能具有的任何属性。)