【发布时间】:2016-05-18 13:06:28
【问题描述】:
当我阅读和尝试时 :-) 我只能在 pList 文件中保存一些简单的数据类型。尽管如此,我还是喜欢使用结构、类等来表示我的数据。这应该尽可能容易地保存到 pList 文件并重新加载。
我明白了,NSData 是 pLists 的有效类型。而且,这是一种通用数据类型。因此,将结构或类变量移动/转换/强制到要保存和重新加载的 NSData 对象中是个好主意吗?那要怎么做呢?
到目前为止,我正在使用类似的东西来保存:
let dict: NSMutableDictionary = ["XYZ": "XYZ"]
// saving values
dict.setObject(myBasicArray, forKey: "BasicArray")
dict.writeToFile(path, atomically: false)
更新: 我使用了提供的代码并将其扩展为处理结构:
import Cocoa
struct SteeringItem {
var ext = String() // extension including dot e.g. ".JPG"
var bitmap = Int() // flag for grouping file types, e.g. photos
init?(ext: String, bitmap: Int) {
// Initialize stored properties.
self.ext = ext
self.bitmap = bitmap
}
}
class Foo {
let one: Int
let two: SteeringItem
init(one:Int, two: SteeringItem) {
self.one = one
self.two = two
}
init?(dict:[String: AnyObject]) {
guard let
one = dict["one"] as? Int,
two = dict["two"] as? SteeringItem else { return nil }
self.one = one
self.two = two
}
func toDictionary() -> [String: AnyObject] {
var retval = [String: AnyObject]()
if let
one = self.one as? AnyObject,
two = self.two as? AnyObject {
retval["one"] = one
retval["two"] = two
}
return retval
}
}
// create struct
let writeStruct = Foo(one: 1, two: SteeringItem(ext: "one",bitmap: 1)!)
print(writeStruct, "\n")
// write to plist
let writeDict = writeStruct.toDictionary() as NSDictionary
let path = ("~/test.plist" as NSString).stringByExpandingTildeInPath
writeDict.writeToFile(path, atomically: true)
// print contents of file
print(try NSString(contentsOfFile: path, encoding: NSUTF8StringEncoding))
// read plist and recreate struct
if let
readDict = NSDictionary(contentsOfFile: path) as? [String:AnyObject],
readStruct = Foo(dict: readDict) {
print(readStruct)
}
但这不再写了。使用 String 可以,使用“struct SteeringItem”则不行!
更新 2:类而不是结构
class SteeringItem : NSObject, NSCoding {
var ext = String() // extension including dot e.g. ".JPG"
var bitmap = Int() // flag for grouping file types, e.g. photos
func encodeWithCoder(aCoder: NSCoder) {
aCoder.encodeObject(ext, forKey: "ext")
aCoder.encodeObject(bitmap, forKey: "bitmap")
}
required convenience init?(coder aDecoder: NSCoder) {
let ext = aDecoder.decodeObjectForKey("ext") as! String
let bitmap = aDecoder.decodeObjectForKey("bitmap") as! Int
self.init(ext: ext, bitmap: bitmap)
}
init?(ext: String, bitmap: Int) {
// Initialize stored properties.
self.ext = ext
self.bitmap = bitmap
super.init()
}
}
【问题讨论】:
-
根据您数据的复杂性,可能值得检查一下
CoreData,看看它是否更合适。 -
如果
init不会失败,你就不需要它。就此而言,如果struct没有定义任何init方法,则它有一个默认的init进行成员初始化。因此,您的SteeringItemstruct中不需要init方法。