如何通过在NsUserDefaults中将数据保存为数组来记住游戏状态

时间:2015-11-14 14:02:38

标签: arrays swift swift2

我已经构建了一个名为Mad Lib的简单应用程序。在这里,您可以在文本字段中输入11个单词。单词得到附加到名为wordStack的列表。单击按钮确定并准备segway将用户带到第二个屏幕。在这里,11个单词作为字符串填充到文本中。

第二页上的txt示例:" Tarzan也被称为(wordStack [1])"

所以,正如我读到的那样,当用户默认访问属性时,内容是不可变的,而且对于像单个字符串或整数这样的简单数据也是如此。我正在努力让这个与这个数组一起工作。

除了

之外,它还有点工作
var wordStack: [String] = []

每次都重置工作堆。

任何帮助我并解释什么是一个好解决方案的人都是绝对的英雄!谢谢!

import UIKit

class ViewController: UIViewController {

  override func viewDidLoad() {
    super.viewDidLoad()
    if let s = userDefault.valueForKey("wordstack"){
        var wordStack: [String] = []
        for i in s as! NSArray {
            print(i)
            wordStack.append(String(i))
            print(wordStack)
        }
    }

    print(wordStack)

    // Do any additional setup after loading the view, typically from a nib.
  }

  override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
  }

  @IBOutlet weak var guess: UILabel!

  @IBOutlet weak var textField: UITextField!

  // Save game state.
  var userDefault = NSUserDefaults.standardUserDefaults()

  // Saves the user's input.
  var wordStack: [String] = []

  func test() {
    let userInput = textField.text
    textField.text = nil
    if wordStack.count < 10 {
        wordStack.append(userInput!)
        guess.text = "\(11-wordStack.count) guesses left!"
        userDefault.setValue(wordStack, forKey: "wordstack")
    } else {
        wordStack.append(userInput!)
    }
  }

  // When pressed enter in the textfield append the input to workstack and refresh textfield for new input.
  @IBAction func enterTextField(sender: AnyObject) {
    test()
  }

  @IBAction func buttonClick(sender: AnyObject) {
    if wordStack.count <= 10 {
        let alertController = UIAlertController(title: "Wacht", message: "Je bent nog niet klaar. \(wordStack.count)/11 woorden ingevuld.",preferredStyle: UIAlertControllerStyle.Alert)
        alertController.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default,handler: nil))
        self.presentViewController(alertController,animated: true, completion: nil)
    }
  }

  override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    let secondViewController: ViewController2 = segue.destinationViewController as! ViewController2
    if wordStack.count > 10 {
    secondViewController.outputMessage = "One of the most silly characters is named Tarzan of the bees. Tarzan is raised by an/a \(wordStack[0]) and lives in the \(wordStack[1]) in the heart of the darkest \(wordStack[2]). He spent most of his time eating \(wordStack[3]) and swinging from tree to \(wordStack[4]). Whenever he gets angry he beats on his chest and says \(wordStack[5])! This is his way cry. Tarzan always dresses in smelly \(wordStack[6]) shorts made of the skin of an/a \(wordStack[7]) and his best friend is an/a \(wordStack[8]) Chimpanzee called Cheetah. He is supposed to be able to speak to elephants and \(wordStack[9]). In the movies, Tarzan plays \(wordStack[10])"

    // reset guesses
    //var count: Int = 0
    }
  }
}

1 个答案:

答案 0 :(得分:1)

问题是您声明了一个局部变量wordStack,它与具有相同名称的实例属性不同。

使用var声明的变量即使从用户默认值中读取值也总是可变的。

简单的解决方案是在var

wordStack之前移除viewDidLoad()关键字

更好的解决方案:

使用

applicationDidFinishLaunching的{​​{1}}中注册键/值对
AppDelegate

然后只需替换

let defaults = NSUserDefaults.standardUserDefaults()
let defaultValues = ["wordstack" : [String]()]
defaults.registerDefaults(defaultValues)

if let s = userDefault.valueForKey("wordstack"){
    var wordStack: [String] = []
    for i in s as! NSArray {
        print(i)
        wordStack.append(String(i))
        print(wordStack)
    }
}

由于空数组wordStack = userDefault.objectForKey("wordstack") 的默认值永远不能为wordStack且类型安全。

注意:除非您确实需要KVC方法,否则请始终使用nil而不是objectForKey