IOS 對(duì)象的歸檔與解檔

歸檔與解檔是IOS中一種序列化與反序列化的方式。對(duì)象要實(shí)現(xiàn)序列化需要遵循NSCoding協(xié)議,而絕大多數(shù)Foundation和Cocoa Touch類都遵循了NSCoding協(xié)議。下面看看具體的實(shí)現(xiàn)方式:

一、在需要?dú)w檔的類中遵循歸檔協(xié)議:
@interface Person : NSObject<NSCoding>
//需要?dú)w檔的屬性
@property (nonatomic, strong)NSString       *name;
@property (nonatomic, assign)NSInteger      age;

@end
二、在歸檔對(duì)象的.m方法中實(shí)現(xiàn)NSCoding的協(xié)議方法
方法一:普通方式實(shí)現(xiàn):
- (void)encodeWithCoder:(NSCoder *)coder
{
    //告訴系統(tǒng)歸檔的屬性是哪些
    [coder encodeObject:self.name forKey:@"name"];
    [coder encodeInteger:self.age forKey:@"age"];
}

- (instancetype)initWithCoder:(NSCoder *)coder
{
    self = [super init];
    if (self) {
        //解檔
        self.name = [coder decodeObjectForKey:@"name"];
        self.age = [coder decodeIntegerForKey:@"age"];
    }
    return self;
}

方法二:使用runtime方法實(shí)現(xiàn):
- (void)encodeWithCoder:(NSCoder *)coder
{
    //告訴系統(tǒng)歸檔的屬性是哪些
    unsigned int count = 0;//表示對(duì)象的屬性個(gè)數(shù)
    Ivar *ivars = class_copyIvarList([Person class], &count);
    for (int i = 0; i<count; i++) {
        //拿到Ivar
        Ivar ivar = ivars[i];
        const char *name = ivar_getName(ivar);//獲取到屬性的C字符串名稱
        NSString *key = [NSString stringWithUTF8String:name];//轉(zhuǎn)成對(duì)應(yīng)的OC名稱
        //歸檔 -- 利用KVC
        [coder encodeObject:[self valueForKey:key] forKey:key];
    }
    free(ivars);//在OC中使用了Copy、Creat、New類型的函數(shù),需要釋放指針?。。ㄗⅲ篈RC管不了C函數(shù))
}

- (instancetype)initWithCoder:(NSCoder *)coder
{
    self = [super init];
    if (self) {
        //解檔
        unsigned int count = 0;
        Ivar *ivars = class_copyIvarList([Person class], &count);
        for (int i = 0; i<count; i++) {
            //拿到Ivar
            Ivar ivar = ivars[i];
            const char *name = ivar_getName(ivar);
            NSString *key = [NSString stringWithUTF8String:name];
            //解檔
            id value = [coder decodeObjectForKey:key];
            // 利用KVC賦值
            [self setValue:value forKey:key];
        }
        free(ivars);
    }
    return self;
}
注:使用runtime的好處不言而喻,無(wú)論對(duì)象有多少屬性都可以通過(guò)這個(gè)for循環(huán)搞定,非常棒。
三、在Controller中實(shí)現(xiàn)具體的存取操作
- (IBAction)save:(UIButton *)sender {
    Person *person = [[Person alloc] init];
    person.name = @"Frank";
    person.age = 18;
    
    //這里以temp路徑為例,存到temp路徑下
    NSString *temp = NSTemporaryDirectory();
    NSString *filePath = [temp stringByAppendingPathComponent:@"obj.data"]; //注:保存文件的擴(kuò)展名可以任意取,不影響。
    NSLog(@"%@", filePath);
    //歸檔
    [NSKeyedArchiver archiveRootObject:person toFile:filePath];
}

- (IBAction)read:(UIButton *)sender {
    //取出歸檔的文件再解檔
    NSString *filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"obj.data"];
    //解檔
    Person *person = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
    NSLog(@"name = %@, age = %ld",person.name,person.age);
}

控制臺(tái)輸出:
name = Frank, age = 18

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容