使用 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)
}
希望对您有所帮助,如果这解决了您的问题,请记得选择答案并点赞。
我是 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)
}
希望对您有所帮助,如果这解决了您的问题,请记得选择答案并点赞。