如何使用 NSCoding 保存结构
Posted
技术标签:
【中文标题】如何使用 NSCoding 保存结构【英文标题】:How to save a struct with NSCoding 【发布时间】:2017-10-18 17:21:27 【问题描述】:如何使用 NSCoding 保存我的结构,这样即使用户使用它也不会改变 关闭应用程序?如果您也能告诉我如何正确实现缺失的代码,我将不胜感激。
使用以下两个新功能进行更新: 这是我的代码:
struct RandomItems: Codable
var items : [String]
var seen = 0
init(items:[String], seen: Int)
self.items = items
self.seen = seen
init(_ items:[String])
self.init(items: items, seen: 0)
mutating func next() -> String
let index = Int(arc4random_uniform(UInt32(items.count - seen)))
let item = items.remove(at:index)
items.append(item)
seen = (seen + 1) % items.count
return item
func toPropertyList() -> [String: Any]
return [
"items": items,
"seen": seen
]
override func viewWillDisappear(_ animated: Bool)
UserDefaults.standard.set(try? PropertyListEncoder().encode(quotes), forKey:"quote2")
override func viewDidAppear(_ animated: Bool)
if let data = UserDefaults.standard.value(forKey:"quote2") as? Data
let quote3 = try? PropertyListDecoder().decode(Array<RandomItems>.self, from: data)
extension QuotesViewController.RandomItems
init?(propertyList: [String: Any])
return nil
如何确保此处覆盖整个 Array?
【问题讨论】:
你需要把它变成一个类。您还需要继承 NSObject 并使其符合 NSCoding Save struct in class to NSUserDefaults using Swift的可能重复 【参考方案1】:对于结构,您应该使用新的Codable 协议。它从 swift 4 开始可用,强烈推荐。
struct RandomItems: Codable
var items: [String]
var seen = 0
extension RandomItems
init?(propertyList: [String: Any])
...
// Example usage
let a = RandomItems(items: ["hello"], seen: 2)
let data: Data = try! JSONEncoder().encode(a)
UserDefaults.standard.set(data, forKey: "MyKey") // Save data to disk
// some time passes
let data2: Data = UserDefaults.standard.data(forKey: "MyKey")! // fetch data from disk
let b = try! JSONDecoder().decode(RandomItems.self, from: data2)
更新
看起来原始海报将结构嵌套在另一个类中。这是嵌套结构的另一个示例。
class QuotesViewController: UIViewController
struct RandomItems: Codable
var items: [String]
var seen = 0
extension QuotesViewController.RandomItems
init(_ items:[String])
self.items = items
init?(propertyList: [String: Any])
guard let items = propertyList["items"] as? [String] else return nil
guard let seen = propertyList["seen"] as? Int else return nil
self.items = items
self.seen = seen
// example usage
let a = QuotesViewController.RandomItems(items: ["hello"], seen: 2)
let data: Data = try! JSONEncoder().encode(a)
UserDefaults.standard.set(data, forKey: "MyKey") // Save data to disk
// some time passes
let data2: Data = UserDefaults.standard.data(forKey: "MyKey")! // fetch data from disk
let b = try! JSONDecoder().decode(QuotesViewController.RandomItems.self, from: data2)
【讨论】:
我必须在哪里插入带有变量声明的三行? @Calimari328 @JoyLucas 我不确定我是否理解您的问题。能改一下吗? let a = .... //错误:无法使用类型为 '(items: [String], seen: Int)' 的参数列表调用类型 'QuotesViewController.RandomItems' 的初始化程序 @Calimari328我该如何解决这个问题? 好吧,也许你的结构需要正确的访问修饰符,或者你需要实现一个公共初始化器。或者,也许您正在向您的结构中添加不可编码的类型。很难用这么少的信息来判断,也不知道您是如何尝试使用它的。 你的结构是什么样的?以上是关于如何使用 NSCoding 保存结构的主要内容,如果未能解决你的问题,请参考以下文章
如何归档 NSDictionary 的 NSArray(使用 NSCoding)?