how to don't get a nil value from NSUserDefaults in ViewDidLoad

萝らか妹 提交于 2019-12-12 02:54:25

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!