我正在尝试将我的自定义类的副本保存到文件中,我的类有两个CGPoints数组,我经常附加它们,它们看起来像这样:
class BlockAttributes: NSObject {
var positions:[CGPoint] = []
var spawns:[CGPoint] = []
}
就使用和访问课程而言,一切都很有效,但归档它并不起作用。我可以在其他类中存档Strings,Bools和Ints数组,但每次我尝试使用NSCoder编码我的CGPoints数组时,我的游戏都会失败。这是我的归档代码:
func encodeWithCoder(coder: NSCoder!) {
coder.encodeObject(positions, forKey: "positions")
coder.encodeObject(spawns, forKey: "spawns")
}
...
class ArchiveData: NSObject {
var documentDirectories:NSArray = []
var documentDirectory:String = ""
var path:String = ""
func saveData(data: BlockAttributes) {
documentDirectories = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
documentDirectory = documentDirectories.objectAtIndex(0) as! String
path = documentDirectory.stringByAppendingPathComponent("data.archive")
if NSKeyedArchiver.archiveRootObject(data, toFile: path) {
print("Success writing to file!")
} else {
print("Unable to write to file!")
}
}
func retrieveData() -> NSObject {
var dataToRetrieve = BlockAttributes()
documentDirectories = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
documentDirectory = documentDirectories.objectAtIndex(0) as! String
path = documentDirectory.stringByAppendingPathComponent("data.archive")
if let dataToRetrieve2 = NSKeyedUnarchiver.unarchiveObjectWithFile(path) as? BlockAttributes {
dataToRetrieve = dataToRetrieve2 as BlockAttributes
}
return(dataToRetrieve)
}
}
.... 并保存:
let archiveData = ArchiveData()
archiveData.saveData(myBlockActionsObject)
我甚至尝试创建自己的自定义类来保存CGPoints,我称之为MyCGPoint(我在某处读到了为某些数据类型创建自定义类可以解决一些NSCoder问题):
class MyCGPoint: NSObject {
var x: CGFloat = 0.0
var y: CGFloat = 0.0
init(X: CGFloat, Y: CGFloat) {
x = X
y = Y
}
override init() {
}
}
...
class BlockAttributes: NSObject {
var positions:[MyCGPoint] = []
var spawns:[MyCGPoint] = []
}
但是,唉,我仍然收到这个错误:
[Game.MyCGPoint encodeWithCoder:]:
unrecognized selector sent to instance 0x137f1d1a0 Game[20953:5814436]
*** Terminating app due to uncaught exception 'NSInvalidArgumentException',
reason: '-[Game.MyCGPoint encodeWithCoder:]:
unrecognized selector sent to instance 0x137f1d1a0'
知道如何使用encodeObject编码我的CGPoints / MyCGPoints数组吗?
答案 0 :(得分:2)
CGPoint
(及其Cocoa的双NSPoint
)是结构,即值类型,因此您无法直接对它们进行编码。将它们包裹在NSValue
:
let positionValues = positions.map { NSValue(point:$0) }
let spawnValues = spawns.map { NSValue(point:$0) }
coder.encodeObject(positionValues, forKey: "positions")
coder.encodeObject(spawnValues, forKey: "spawns")
// Decode:
positons = (coder.decodeObjectForKey("positions") as! [NSValue]).map { $0.pointValue }
spawns = (coder.decodeObjectForKey("spawns") as! [NSValue]).map { $0.pointValue }
当您编写自定义包装类时,您必须使NSCoding
符合NSValeu
,width:100%
已经为您完成了免费。
答案 1 :(得分:2)
您可以将它们转换为字符串:
//To string
let point = CGPointMake(0, 0)
let string = NSStringFromCGPoint(point)
//Or if you want String instead of NSString
let string = String(point)
//From string
let point2 = CGPointFromString(string)