使用 NSUserDefaults 保存对象数组

using NSUserDefaults to save an array of objects


我是 swift 的新手,我正在尝试构建一个包含前 5 名玩家姓名和得分的游戏,如果我只是将玩家添加到一个数组中而不是重新启动游戏 "deletes"播放器,所以我正在尝试使用 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 )
        }
    }

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

谢谢!

需要可以致电

playerDefaults.synchronize()

将数据保存为默认值。

编辑
正如 facumenzella 所说,您的另一个问题是在默认值中存储自定义 class 对象。要解决这个问题,您需要在自定义播放器 class 中实现方法,告诉它如何转换为数据。那么你应该在将它存储在默认值之前序列化对象。

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

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

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

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

您的播放器 class 需要符合 NSCoding,并且您需要存储播放器数组的存档数据并在提取数据时取消存档。

Class:

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 & Archiving/Unarchiving :

    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)
    }

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