【问题标题】:using NSUserDefaults to save an array of objects使用 NSUserDefaults 保存对象数组
【发布时间】:2016-10-04 17:35:25
【问题描述】:


我是 swift 新手,我正在尝试构建一个包含前 5 名玩家姓名和得分的游戏,如果我只是将玩家添加到数组中,然后重新启动游戏,它会“删除”玩家,所以我正在尝试使用 NSUserDefaults(我只需要存储 5 个字符串和 5 个整数),无论如何它都不起作用, 代码是:

class scoreController: UITableViewController {

    var playersArray:[Player] = [Player]()

    var nameFromGame = "" //name from game vc
    var timeFromGame = 0 //time from game vc

    let tmpPlayer = Player(playerName: "", scoreTime: 0)
    let playerDefaults = NSUserDefaults.standardUserDefaults()

    override func viewDidLoad() {
        super.viewDidLoad()

        let player1 = Player(playerName: "Bil", scoreTime: 50)
        let player2 = Player(playerName: "Bob", scoreTime: 100)


        playersArray.append(player1)
        playersArray.append(player2)

         tmpPlayer.playerName = nameFromGame
         tmpPlayer.scoreTime = timeFromGame
         playersArray.append(tmpPlayer)

         playerDefaults.setObject(playersArray[11], forKey: "players")

            print(playersArray )
        }
    }

我现在只是想保存它,但它崩溃了,有人知道为什么吗?以及如何将其存储在我的应用程序中以便保存数据?

谢谢!

【问题讨论】:

    标签: swift2 xcode7 nsuserdefaults


    【解决方案1】:

    您的播放器对象可能是这里的问题。您必须在您的播放器类中实现两种方法(我不是 swift 大师,但很可能是同样的错误):

    - (void)encodeWithCoder:(NSCoder *)encoder;
    - (id)initWithCoder:(NSCoder *)decoder;
    

    这应该适合你。 希望对你有帮助!!

    PD:检查这个答案 How to store custom objects in NSUserDefaults

    【讨论】:

    【解决方案2】:

    您的 Player 类需要符合 NSCoding,并且您需要存储您的 player 数组的存档数据,并在提取数据时将其取消存档。

    类:

    class Player: NSObject, NSCoding {
        var playerName: String
        var scoreTime: Int
    
        init(playerName: String, scoreTime: Int) {
            self.playerName = playerName
            self.scoreTime = scoreTime
        }
    
        func encodeWithCoder(aCoder: NSCoder) {
            aCoder.encodeInteger(scoreTime, forKey: "score_time")
            aCoder.encodeObject(playerName, forKey: "player_name")
        }
    
        required convenience init?(coder decoder: NSCoder) {
            guard let playerName = decoder.decodeObjectForKey("player_name") as? String else {
                return nil
            }
            self.init(playerName: playerName, scoreTime: decoder.decodeIntegerForKey("score_time"))
        }
    }
    

    NSUserdefaults 和存档/取消存档:

        let player1 = Player(playerName: "Bil", scoreTime: 50)
        let player2 = Player(playerName: "Bob", scoreTime: 100)
    
        let playersArray = [player1, player2]
        let playersData  = NSKeyedArchiver.archivedDataWithRootObject(playersArray)
    
        let defaults = NSUserDefaults.standardUserDefaults()
        defaults.setObject(playersData, forKey: "players")
        defaults.synchronize()
    
        if let playersArrayData = defaults.objectForKey("players") as? NSData {
            let unarchivedPlayers = NSKeyedUnarchiver.unarchiveObjectWithData(playersArrayData) as! [Player]
            print(unarchivedPlayers)
        }
    

    希望这会有所帮助,如果这解决了您的问题,请记得选择答案并投票。

    【讨论】:

      【解决方案3】:

      需要可以调用

      playerDefaults.synchronize()
      

      以默认值保存数据。

      编辑
      正如 faumenzella 所说,您的另一个问题是将自定义类对象存储在默认值中。为了解决这个问题,您需要在自定义 Player 类中实现方法,告诉它如何转换为数据。然后,您应该先序列化对象,然后再将其存储在默认值中。

      【讨论】:

      • 不,不需要,操作系统会定期调用该方法。
      • 但是,如果他在设置默认值后不久就访问它们,他应该在更改后进行同步。此外,应用程序总是有可能崩溃或被用户停止,在这种情况下可能不会发生周期同步。
      猜你喜欢
      • 2021-04-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-13
      • 2011-07-17
      • 2011-07-05
      相关资源
      最近更新 更多