macOS对象编解码NSCoder
macOS对象编解码NSCoder

macOS对象编解码NSCoder

NSCoder 是 macOS/iOS 中用于 对象编码与解码(序列化 / 反序列化) 的基础类,来自 Apple 的 Foundation 框架。它是所有编码器(如 NSKeyedArchiver、NSUnarchiver、PropertyListEncoder 等)背后的核心抽象。

NSCoder 是什么?

NSCoder 是一个抽象类,定义了用于保存或读取对象数据的方法接口,常用于:

1、存档和恢复对象:NSKeyedArchiver / NSKeyedUnarchiver。

2、Storyboard 解码:init?(coder:)。

3、将对象写入 plist 文件:PropertyListEncoder 背后也用到。

4、Core Data 中转换模型:一些 NSManagedObject 也用它归档属性。

常见子类

1、NSKeyedArchiver:对象 → 二进制(写入磁盘)。

2、NSKeyedUnarchiver:二进制 → 对象(从磁盘读取)。

3、NSUnarchiver / NSArchiver:旧版 API(现在基本不用)。

常用方法

1、解码数据(从磁盘读取时用)

func decodeObject(forKey key: String) -> Any?
func decodeBool(forKey key: String) -> Bool
func decodeInt(forKey key: String) -> Int
func decodeDouble(forKey key: String) -> Double

2、编码数据(存储时用)      

func encode(_ objv: Any?, forKey key: String)
func encode(_ boolv: Bool, forKey key: String)
func encode(_ intv: Int, forKey key: String)

使用场景

1、自定义类支持存档(配合 NSCoding 协议)

class Person: NSObject, NSCoding {
    var name: String
    var age: Int

    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }

    func encode(with coder: NSCoder) {
        coder.encode(name, forKey: "name")
        coder.encode(age, forKey: "age")
    }

    required convenience init?(coder: NSCoder) {
        let name = coder.decodeObject(forKey: "name") as? String ?? ""
        let age = coder.decodeInteger(forKey: "age")
        self.init(name: name, age: age)
    }
}

然后存档:

let person = Person(name: "Alice", age: 30)
let data = try NSKeyedArchiver.archivedData(withRootObject: person, requiringSecureCoding: false)
try data.write(to: someURL)

2、在XIB或Storyboard加载视图时的解码器

required init?(coder: NSCoder) {
    super.init(coder: coder)
    // 解码 UI 或其他属性
}

这就是从 storyboard 中加载控件时,Swift 利用 NSCoder 把控件还原出来的。

3、安全解码

推荐使用:

NSKeyedArchiver.archivedData(withRootObject:..., requiringSecureCoding: true)

让类实现:

class Person: NSObject, NSSecureCoding {
    static var supportsSecureCoding: Bool { true }
    ...
}

和 Swift Codable 关系

1、基于类:NSCoding / NSCoder基于类(NSObject),Swift Codable基于类或结构体。

2、安全性:NSCoding / NSCoder需手动实现Secure Coding,Swift Codable自动实现。

3、数据格式:NSCoding / NSCoder适用于二进制plist,Swift Codable适用于JSON / plist / 自定义。

总结

当需要解码 Storyboard / XIB 中的UI控件,可以在init(coder:)中使用NSCoder。

如果存储自定义类到本地,使用NSKeyedArchiver(底层是NSCoder)。

   

如果您认为这篇文章给您带来了帮助,您可以在此通过支付宝或者微信打赏网站开发者。

欢迎加入我们的 微信交流群QQ交流群,交流更多精彩内容!
微信交流群二维码 QQ交流群二维码

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注