将自定义对象转换为 NSData Swift
converting custom object to NSData Swift
我一直在整个互联网上进行研究,尤其是 Stack overflow,以及我自己在家里的参考资料,但我一直无法弄清楚我的代码有什么问题。我花了一天的大部分时间试图解决这个问题,我希望这里有人能帮助我指明正确的方向。
设置:
我有一个在 Swift 3.0 中构建的国际象棋应用程序,结构如下:BoardModel 是 class,它包含有关游戏的所有数据,Piece 是 class在板模型中,它在 BoardModel 中保存关于自身的数据,Piece 也有一个 PieceType 枚举,用于 .knight、.king 等。
BoardModel 有一个代表棋盘的二维棋子数组。现在,每走一步,我都想将游戏数据保存在 Game Center 中,但在我尝试存储游戏数据之前,编码会抛出一个错误,这就是我所在的位置。该错误仅指向 AppDelegate 并带有以下语句:"Thread: 1 signal SIGABRT"
。
这是与 Piece 一起出现问题的代码 class:
let pieceData = NSKeyedArchiver.archivedData(withRootObject: board.board[0][0]) // where the error is thrown
class Piece: NSObject, NSCoding {
var isSelected: Bool
var type: PieceType
var isWhite: Bool
var isFirstMove: Bool
var symbol: String!
var position: (row: Int, col: Int)!
override init() {
isSelected = false
type = PieceType.empty
isWhite = true
isFirstMove = true
}
required init(coder aDecoder: NSCoder) {
isSelected = aDecoder.decodeBool(forKey: "isSelected")
type = aDecoder.decodeObject(forKey: "type") as! BoardModel.PieceType
isWhite = aDecoder.decodeBool(forKey: "isWhite")
isFirstMove = aDecoder.decodeBool(forKey: "isFirstMove")
symbol = aDecoder.decodeObject(forKey: "symbol") as! String
position = aDecoder.decodeObject(forKey: "position") as! (Int, Int)
}
func encode(with aCoder: NSCoder) {
aCoder.encode(isSelected, forKey: "isSelected")
aCoder.encode(type, forKey: "type")
aCoder.encode(isWhite, forKey: "isWhite")
aCoder.encode(isFirstMove, forKey: "isFirstMove")
aCoder.encode(symbol, forKey: "symbol")
aCoder.encode(position, forKey: "position")
}
init(isSelected: Bool, type: PieceType, isWhite: Bool, isFirstMove: Bool, symbol: String, position: (Int, Int)) {
self.isSelected = isSelected
self.type = type
self.isWhite = isWhite
self.isFirstMove = isFirstMove
self.symbol = symbol
self.position = position
}
func setPosition(to newPosition: (row: Int, col: Int)) {
position = newPosition
}
}
如果您的 Enum
是这样 PieceType
并且类型是 Int
enum PieceType : Int {
case empty
case notEmpty
}
然后这样写encode
和decode
方法
required init(coder aDecoder: NSCoder) {
isSelected = aDecoder.decodeBool(forKey: "isSelected")
type = PieceType(rawValue: aDecoder.decodeObject(forKey: "type") as! Int)!
isWhite = aDecoder.decodeBool(forKey: "isWhite")
isFirstMove = aDecoder.decodeBool(forKey: "isFirstMove")
symbol = aDecoder.decodeObject(forKey: "symbol") as! String
position = aDecoder.decodeObject(forKey: "position") as! (Int, Int)
}
func encode(with aCoder: NSCoder) {
aCoder.encode(isSelected, forKey: "isSelected")
aCoder.encode(type.rawValue, forKey: "type")
aCoder.encode(isWhite, forKey: "isWhite")
aCoder.encode(isFirstMove, forKey: "isFirstMove")
aCoder.encode(symbol, forKey: "symbol")
aCoder.encode(position.row, forKey: "position.row")
aCoder.encode(position.col, forKey: "position.col")
}
我已经检查了下面的代码并且它有效
let pice = Piece(isSelected: true, type: .empty, isWhite: true, isFirstMove: true, symbol: "Test", position: (2, 10))
let pieceData = NSKeyedArchiver.archivedData(withRootObject:pice)
print(pieceData)
输出是
386 bytes
我一直在整个互联网上进行研究,尤其是 Stack overflow,以及我自己在家里的参考资料,但我一直无法弄清楚我的代码有什么问题。我花了一天的大部分时间试图解决这个问题,我希望这里有人能帮助我指明正确的方向。
设置:
我有一个在 Swift 3.0 中构建的国际象棋应用程序,结构如下:BoardModel 是 class,它包含有关游戏的所有数据,Piece 是 class在板模型中,它在 BoardModel 中保存关于自身的数据,Piece 也有一个 PieceType 枚举,用于 .knight、.king 等。
BoardModel 有一个代表棋盘的二维棋子数组。现在,每走一步,我都想将游戏数据保存在 Game Center 中,但在我尝试存储游戏数据之前,编码会抛出一个错误,这就是我所在的位置。该错误仅指向 AppDelegate 并带有以下语句:"Thread: 1 signal SIGABRT"
。
这是与 Piece 一起出现问题的代码 class:
let pieceData = NSKeyedArchiver.archivedData(withRootObject: board.board[0][0]) // where the error is thrown
class Piece: NSObject, NSCoding {
var isSelected: Bool
var type: PieceType
var isWhite: Bool
var isFirstMove: Bool
var symbol: String!
var position: (row: Int, col: Int)!
override init() {
isSelected = false
type = PieceType.empty
isWhite = true
isFirstMove = true
}
required init(coder aDecoder: NSCoder) {
isSelected = aDecoder.decodeBool(forKey: "isSelected")
type = aDecoder.decodeObject(forKey: "type") as! BoardModel.PieceType
isWhite = aDecoder.decodeBool(forKey: "isWhite")
isFirstMove = aDecoder.decodeBool(forKey: "isFirstMove")
symbol = aDecoder.decodeObject(forKey: "symbol") as! String
position = aDecoder.decodeObject(forKey: "position") as! (Int, Int)
}
func encode(with aCoder: NSCoder) {
aCoder.encode(isSelected, forKey: "isSelected")
aCoder.encode(type, forKey: "type")
aCoder.encode(isWhite, forKey: "isWhite")
aCoder.encode(isFirstMove, forKey: "isFirstMove")
aCoder.encode(symbol, forKey: "symbol")
aCoder.encode(position, forKey: "position")
}
init(isSelected: Bool, type: PieceType, isWhite: Bool, isFirstMove: Bool, symbol: String, position: (Int, Int)) {
self.isSelected = isSelected
self.type = type
self.isWhite = isWhite
self.isFirstMove = isFirstMove
self.symbol = symbol
self.position = position
}
func setPosition(to newPosition: (row: Int, col: Int)) {
position = newPosition
}
}
如果您的 Enum
是这样 PieceType
并且类型是 Int
enum PieceType : Int {
case empty
case notEmpty
}
然后这样写encode
和decode
方法
required init(coder aDecoder: NSCoder) {
isSelected = aDecoder.decodeBool(forKey: "isSelected")
type = PieceType(rawValue: aDecoder.decodeObject(forKey: "type") as! Int)!
isWhite = aDecoder.decodeBool(forKey: "isWhite")
isFirstMove = aDecoder.decodeBool(forKey: "isFirstMove")
symbol = aDecoder.decodeObject(forKey: "symbol") as! String
position = aDecoder.decodeObject(forKey: "position") as! (Int, Int)
}
func encode(with aCoder: NSCoder) {
aCoder.encode(isSelected, forKey: "isSelected")
aCoder.encode(type.rawValue, forKey: "type")
aCoder.encode(isWhite, forKey: "isWhite")
aCoder.encode(isFirstMove, forKey: "isFirstMove")
aCoder.encode(symbol, forKey: "symbol")
aCoder.encode(position.row, forKey: "position.row")
aCoder.encode(position.col, forKey: "position.col")
}
我已经检查了下面的代码并且它有效
let pice = Piece(isSelected: true, type: .empty, isWhite: true, isFirstMove: true, symbol: "Test", position: (2, 10))
let pieceData = NSKeyedArchiver.archivedData(withRootObject:pice)
print(pieceData)
输出是
386 bytes