iOS - 对象归档

       所谓对象归档,其实就是类似于其他语言中的序列化机制,归档通常就是用某种格式把一个或者多个对象保存到指定的文件中,方便以后从文件中恢复它们.通常来说,归档包含两方面的操作:一方面需要把对象写入指定的文件,另一方面需要从文件中恢复这些对象.这是一种常用的数据化持久存储的方式。如下图讲多个对象进行归档操作:



使用NSKeyedArchiver归档

   与NSKeyedArchiver相对应的还有一个NSKeyedUnarchiver类,其中NSKeyedArchiver负责就爱那个对象归档到指定的文件中,而NSKeyedUnarchiver则负责从文件中恢复这些对象.
   NSKeyedArchiver会创建一种所谓的带键(keyed)的档案,在这种归档格式中,无论归档哪个对象,程序都需要为该对象分配一个key(即所谓的键),当程序希望从文件中恢复这些对象时,也需要根据key进行检索.
   
NSKeyedArchiver与NSKeyedUnarchiver的用法有如下:
1)直接调用NSKeyedArchiver的+ (NSData *)archivedDataWithRootObject:(id)rootObject;

+ (BOOL)archiveRootObject:(id)rootObject toFile:(NSString *)path;类方法将指定的对象作为root进行归档,存储到指定的路径下;

2)获取规定对象时,则调用NSKeyedUnarchiver的+ (nullable id)unarchiveObjectWithData:(NSData *)data;

+ (nullable id)unarchiveObjectWithFile:(NSString *)path;方法.

直接使用如下:


归档自定义对象

1)如果对象是NSString、NSDictionary、NSArray、NSData、NSNumber等类型,可以直接用NSKeyedArchiver进行归档和恢复
2)但不是所有的对象都可以直接用这种方法进行归档,只有遵守了NSCoding协议的对象才可以,所以要归档自定义对象,那么要遵守NSCoding协议并实现有2个方法:encodeWithCoder:每次归档对象时,都会调用这个方法。一般在这个方法里面指定如何归档对象中的每个实例变量,可以使用encodeObject:forKey:方法归档实例变量 initWithCoder:每次从文件中恢复(解码)对象时,都会调用这个方法。一般在这个方法里面指定如何解码文件中的数据为对象的实例变量,可以使用decodeObject:forKey方法解码实例变量.

例子如下:


自定义类的实现:



使用归档实现深复制


想详细了解归档方面的内容,可以看官方文档


使用Swift实现自定义归档

定义一个Book类,遵守NSCoding协议,实现协议方法

class Book: NSObject, NSCoding {
    var title: String
    var author: String
    var pageCount: Int

    init(title: String, author: String, pageCount: Int) {
        self.title = title
        self.author = author
        self.pageCount = pageCount
    }

    // MARK: NSCoding
    required convenience init?(coder aDecoder: NSCoder) {
        guard let title = aDecoder.decodeObject(forKey: "title") as? String,
            let author = aDecoder.decodeObject(forKey: "author") as? String else { return nil }
        let pageCount = aDecoder.decodeInteger(forKey: "pageCount") 
        self.init(title: title, author: author, pageCount: pageCount)
    }

    func encode(with aCoder: NSCoder) {
        aCoder.encode(title, forKey: "title")
        aCoder.encode(author, forKey: "author")
        aCoder.encode(pageCount, forKey: "pageCount")
    }
}

使用归档

 let document = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
 let filePath = document.appending("/book.archive")

 let book = Book(title: "iOS developer", author: "Apple", pageCount: 500)
 if NSKeyedArchiver.archiveRootObject(book, toFile: filePath) {
     print("archive book success")
 } else {
     print("archive book failure")
 }

 if let data = NSKeyedUnarchiver.unarchiveObject(withFile: filePath) as? Book {
     print("book: \(data.title)")
 }

配合UserDefaults存储多个对象

func archiveBooks() {
        var books: [Book] = []
        for _ in 0..<10 {
            let book = Book(title: "iOS developer", author: "Apple", pageCount: 500)
            books.append(book)
        }

        let defaults = UserDefaults.standard
        let data = NSKeyedArchiver.archivedData(withRootObject: books)
        defaults.set(data, forKey: "books")
        defaults.synchronize()

        if let data = defaults.object(forKey: "books") as? Data,
            let books = NSKeyedUnarchiver.unarchiveObject(with: data) as? [Book] {
            print(books)
        }
    }

参考

NSCoding/NSKeyedArchiver





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值