问题
I have a case where when my viewControler
starts in viewDidLoad
I have to load some data using NSUserDefaults.standardUserDefaults()
which doesn't exist in this monent. This data are saved when I tap send Button
in the same viewController
and I need this data when I open this viewController
again. Now it looks like that:
var orderHistory = [String:String]()
vievDidLoad(){
let userDefault = NSUserDefaults.standardUserDefaults()
let orderHistory = userDefault.objectForKey("orderHistory")
if orderHistory == nil {
self.orderHistory = orderHistory["name":"", "surname":""] as! [String:String]
} else {
self.orderHistory = orderHistory as! [String:String]
{
}// end viewDidLoad
In this moment I recieve an imformation, I have a problem with memory. How should I avoid this situation?
回答1:
As Leo Dabus said you should try using the ?? nil coalescing operator. ObjectForKey does not provide a default value because it doesnt know what kind of object it is until you set it the first time. This results in a nil crash if you try to access it value without having it set once.
Compare this to say "boolForKey" where you dont have to do this, because it knows you are dealing with boolean values and therefore defaults to false automatically.
You also dont have to create 2 orderHistory dictionaries, it just makes your code more confusing.
Try this instead
var orderHistory = [String:String]()
vievDidLoad(){
let userDefault = NSUserDefaults.standardUserDefaults()
orderHistory = userDefault.objectForKey("orderHistory") as? [String: String] ?? orderHistory
//than just use the 1 dictionary without the if statements or creating another one.
}// end viewDidLoad
You check if saved data exists (as? [String: String]) and update the dictionary accordingly. If no saved data exists it will use the default values in orderHistory (?? orderHistory), which in your case is an empty dictionary. This way you dont have to do a nil check, its all done in that one line.
Also try putting your keys into structs or global files so that you avoid typos. I see people not doing this all the time and its really bad practice. So for example, above your class create a struct
struct Key {
static let orderHistory = "OrderHistory"
}
and use it like so
...objectForKey(Key.orderHistory)
回答2:
This code makes no sense:
if orderHistory == nil
{
self.orderHistory = orderHistory["name":"", "surname":""] as! [String:String]
}
The if statement guarantees that orderHistory
is nil, thereby guaranteeing that the attempt to fetch keys from orderHistory
will crash. Actually, that doesn't look like valid Swift. I would expect that line to throw a compiler error.
Are you trying to create a new dictionary?
If so, your code should read like this:
if orderHistory == nil
{
self.orderHistory = ["name":"", "surname":""]
}
来源:https://stackoverflow.com/questions/35880173/how-to-dont-get-a-nil-value-from-nsuserdefaults-in-viewdidload