【问题标题】:What is the best way to save an array to a file that can be reloaded将数组保存到可以重新加载的文件的最佳方法是什么
【发布时间】:2017-01-04 15:56:57
【问题描述】:

与游戏如何让您保存进度类似,我在 iOS 中有一个应用程序,它将用户的进度存储在一个数组中。我想将该数组存储到一个文件中,以便当用户重新打开他们的应用程序时,这个文件会加载他们的当前状态。

【问题讨论】:

  • 同意感谢您提出的澄清问题。我已将问题更新为针对 iOS。
  • 不,不要在标题中添加您的技术。这就是标签的用途。
  • 要求“最佳”方式的问题通常是基于意见的,如果不是太宽泛的话。
  • @JAL 不一定。 原则上要求最佳实践并没有错。
  • @LeoNatan 我不同意。这个问题可以改写为不关注“最佳方式”,但像这样的问题是离题的,要么是 POB 要么太宽泛。在这种情况下,我认为这个问题太宽泛了。 meta.stackoverflow.com/q/265928/2415822

标签: ios arrays swift storage


【解决方案1】:

最简单的方法是使用NSKeyedArchiver/NSKeyedUnarchiver 对,并确保数组中的每个对象都符合NSCoding。你可以阅读here 了解它。

  NSKeyedArchiver.archiveRootObject(myArray, toFile: filePath)

然后解压

if let array = NSKeyedUnarchiver.unarchiveObjectWithFile(filePath) as? [Any] {
    objects = array
}

这是一个符合NSCoding 的示例对象(摘自上面链接的文章):

class Person : NSObject, NSCoding {

    struct Keys {
        static let Name = "name"
        static let Age = "age"
    }

    var name = ""
    var age = 0

    init(dictionary: [String : AnyObject]) {
        name = dictionary[Keys.Name] as! String
        age = dictionary[Keys.Age] as! Int
    }

    public func encode(with archiver: NSCoder) {
        archiver.encodeObject(name, forKey: Keys.Name)
        archiver.encodeObject(age, forKey: Keys.Age)
    }

    required init(coder unarchiver: NSCoder) {
        super.init()
        name = unarchiver.decodeObjectForKey(Keys.Name) as! String
        age = unarchiver.decodeObjectForKey(Keys.Age) as! Int
    }
}

【讨论】:

  • 您不需要NSKeyedArchiver 将普通数组存储到NSUserDefaults,只有当它是一个自定义对象数组时才需要它。
  • @Rikh:是的,但这是最普遍的情况,我假设任何非平凡应用中的游戏状态都会使用某种自定义对象。
  • @Rikh,如果所有对象都是属性列表对象,则只能将数组保存为用户默认值,如我的回答中所述。有很多类型的系统对象不是自定义的,但不在非常短的属性列表对象列表中。
  • @Rikh,还请注意,OP 询问是否将数组保存到文件,而不是保存到 NSUserDefaults。
  • 那我错了!我对系统对象一无所知!我错误地认为您通常会使用属性列表对象或模型!
【解决方案2】:

如果数组中的对象都是“属性列表对象”(字典、数组、字符串、数字(整数和浮点数)、日期、二进制数据和布尔值),那么您可以使用数组方法 write(toFile:atomically:) 来将数组保存到文件中,然后使用arrayWithContentsOfFile:init(contentsOfFile:) 重新加载生成的文件。

如果数组的object graph 中有不是属性列表对象的对象,那么该方法将不起作用。在这种情况下,@BogdanFarca 建议使用NSKeyedArchiver/NSKeyedUnarchiver 将是一个不错的选择。

【讨论】:

  • 这听起来是正确的方法。我一直在寻找一个明确的例子,说明如何在 Swift 3.0 中为数组执行此操作,但没有找到任何东西。你能指出一个如何做到这一点的工作示例吗?
  • 一行代码。 array.write(toFile: path, atomically: true)。路径需要指向允许写入的目录,例如文档目录。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-02
  • 1970-01-01
  • 2015-07-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多