Swift 5
如果你在使用苹果平台,现在可以使用 Codable
。请参阅文档。
Swift 3
这是从 Xcode 8.2.1 中的 Playground 中复制粘贴的内容,可以正常工作。与其他答案相比,它要简单一些。
import Foundation
enum WhizzoKind {
case floom
case bzzz
}
struct Whizzo {
let name: String
let num: Int
let kind:WhizzoKind
static func archive(w:Whizzo) -> Data {
var fw = w
return Data(bytes: &fw, count: MemoryLayout<Whizzo>.stride)
}
static func unarchive(d:Data) -> Whizzo {
guard d.count == MemoryLayout<Whizzo>.stride else {
fatalError("BOOM!")
}
var w:Whizzo?
d.withUnsafeBytes({(bytes: UnsafePointer<Whizzo>)->Void in
w = UnsafePointer<Whizzo>(bytes).pointee
})
return w!
}
}
let thing = Whizzo(name:"Bob", num:77, kind:.bzzz)
print("thing = \(thing)")
let dataThing = Whizzo.archive(w: thing)
let convertedThing = Whizzo.unarchive(d: dataThing)
print("convertedThing = \(convertedThing)")
注释
我无法将archive
和unarchive
实例方法制作成,因为Data.init(bytes: count:)
对于bytes
参数是可变的。而self
不可变,所以...这对我来说毫无意义。
WhizzoKind
枚举是存在的,因为那是我关心的内容。它对于示例并不重要。有些人可能像我一样对枚举很担心。
我必须从其他4个 SO 问题/答案中拼凑出这个答案:
以及这些文档:
- http://swiftdoc.org/v3.1/type/UnsafePointer/
并且冥想 Swift 闭包语法,直到我想尖叫。
所以感谢那些其他 SO 提问者/作者。
更新
所以这将不能在不同设备之间工作。例如,从 iPhone 7 发送到 Apple Watch。因为 stride
不同。上面的示例在 iPhone 7 模拟器上是 80 字节,但在 Apple Watch Series 2 模拟器上只有 40 字节。
看起来 @niklassaers 的方法(而不是语法)仍然是唯一可行的方法。我会将此答案保留在这里,因为它可能会帮助其他人了解所有围绕此主题的新 Swift 3 语法和 API 更改。
我们唯一的真正希望是这个 Swift 提案:https://github.com/apple/swift-evolution/blob/master/proposals/0166-swift-archival-serialization.md