美文网首页
NSCoding的简单使用

NSCoding的简单使用

作者: 数字d | 来源:发表于2020-01-17 15:39 被阅读0次

    NSCoding是一个协议,如果实现这个协议,就可以将这个类转换成NSData,并互相转换

    使用场景1,NSUserDefaults存储数据时,需要转成NSData

    使用场景2,因为NSData提供了一个方法来存储数据

    NSCorder类是一个抽象类,用来被其他的类继承。

    NSCorder定义了一些接口,使数据从内存到其他格式的转换。

    NSKeyedArchiver和NSKeyedUnarchiver

    NSKeyedArchiver将自定义类转化成NSData实例,类里面的每一个值对应一个key

    NSKeyedUnarchiver将NSData实例根据key的值还原成自定义的类。

    NSCoding和NSSecureCoding(iOS6以后)

    NSCoding安全性不高,存储到rom中会被篡改

    NSSecureCoding安全的,会进行类型检查,类型不匹配,就抛出异常。

    具体代码实现地址:https://gitee.com/xgkp/NSSecureCodingDemoo.git

    说明:
    创建一个工程名字叫NSSecureCodingDemoo

    创建一个类叫MyDog

    MyDog.h中代码,注意这里的<NSSecureCoding>

    #import <Foundation/Foundation.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface MyDog : NSObject<NSSecureCoding>
    
    @property (nonatomic,strong) NSString *name;
    @property (nonatomic,assign) NSInteger age;
    
    @end
    
    NS_ASSUME_NONNULL_END
    

    在MyDog.h中的代码

    #import "MyDog.h"
    
    @implementation MyDog
    
    +(BOOL)supportsSecureCoding
    {
        return YES;
    }
    
    -(instancetype)initWithCoder:(NSCoder *)coder
    {
        if (self = [super init]) {
            if (coder) {
                _name = [coder decodeObjectOfClass:[NSString class] forKey:@"name"];
                _age = [coder decodeIntegerForKey:@"age"];
            }
        }
        return self;
    }
    
    -(void)encodeWithCoder:(NSCoder *)coder
    {
        [coder encodeObject:_name forKey:@"name"];
        [coder encodeInteger:_age forKey:@"age"];
    }
    
    
    @end
    

    viewcontroller中的代码,注意这里的实现是在iOS13之后,demo的版本是在iOS13及以后的实现,部分方法如果在iOS12以前实现有所不同

    
    #import "ViewController.h"
    #import "MyDog.h"
    
    @interface ViewController ()
    @property (nonatomic,strong) NSData *archiveData;
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view.
    }
    
    - (IBAction)dogToData:(id)sender {
    //    myDog to nsdata
        NSData * data = [NSMutableData data];
    
        MyDog * dog = [[MyDog alloc] init];
        dog.name = @"泰迪";
        dog.age= 2;
        NSError *error = nil;
    
        data = [NSKeyedArchiver archivedDataWithRootObject:dog requiringSecureCoding:YES error:&error];
        
        if (data == nil || error) {
            NSLog(@"%@",error);
            return;
        }
        _archiveData = [data copy];
        
    }
    
    - (IBAction)dataToDog:(id)sender {
        
    //    data -> mydog
        NSError * error = nil;
        MyDog * dog = [NSKeyedUnarchiver unarchivedObjectOfClass:[MyDog class] fromData:_archiveData error:&error];
        NSLog(@"%@",dog.name);
        NSLog(@"%ld",dog.age);
    }
    
    
    
    
    
    @end
    
    
    

    在实际开发中可以直接使用category来实现NSKeyedUnarchiver+ConvertNSData

    //
    //  NSKeyedUnarchiver+ConvertNSData.h
    //  NSSecureCodingDemoo
    //
    //  Created by hpkj on 2020/1/19.
    //
    
    
    #import <Foundation/Foundation.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface NSKeyedUnarchiver (ConvertNSData)
    +(id<NSSecureCoding>)customInstanceFromData:(NSData *)data ForClass:(Class)classType;
    @end
    
    NS_ASSUME_NONNULL_END
    
    
    
    
    //
    //  NSKeyedUnarchiver+ConvertNSData.m
    //  NSSecureCodingDemoo
    //
    //  Created by hpkj on 2020/1/19.
    //
    
    #import "NSKeyedUnarchiver+ConvertNSData.h"
    
    
    
    @implementation NSKeyedUnarchiver (ConvertNSData)
    +(id<NSSecureCoding>)customInstanceFromData:(NSData *)data ForClass:(Class)classType
    {
        NSError * error = nil;
         return  [NSKeyedUnarchiver unarchivedObjectOfClass:[classType class] fromData:data error:&error];
    }
    
    @end
    
    
    

    Category的NSKeyedArchiver+ConvertNSData.h实现

    //
    //  NSKeyedArchiver+ConvertNSData.h
    //  NSSecureCodingDemoo
    //
    //  Created by hpkj on 2020/1/19.
    //
    
    #import <Foundation/Foundation.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface NSKeyedArchiver (ConvertNSData)
    +(NSData *)dataWithCustomClass:(id<NSSecureCoding>)customClass;
    
    @end
    
    NS_ASSUME_NONNULL_END
    
    
    //
    //  NSKeyedArchiver+ConvertNSData.m
    //  NSSecureCodingDemoo
    //
    //  Created by hpkj on 2020/1/19.
    //
    
    #import "NSKeyedArchiver+ConvertNSData.h"
    
    
    
    @implementation NSKeyedArchiver (ConvertNSData)
    +(NSData *)dataWithCustomClass:(id<NSSecureCoding>)customClass
    {
        NSMutableData * data = [NSMutableData data];
        NSError *error = nil;
        data = [NSKeyedArchiver archivedDataWithRootObject:customClass requiringSecureCoding:YES error:&error];
        return [data copy];
    }
    
    
    
    
    @end
    

    总结:如果希望自定义类或者model数据类能够被存储到缓存中,可以将类的实现中加上NSSecureCoding协议的实现

    相关文章

      网友评论

          本文标题:NSCoding的简单使用

          本文链接:https://www.haomeiwen.com/subject/rinczctx.html