美文网首页
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简单使用

    viewController.m文件的调用 person.h 文件 person.m文件

  • NSCoding的简单使用

    NSCoding是一个协议,如果实现这个协议,就可以将这个类转换成NSData,并互相转换 使用场景1,NSUse...

  • NSCoding 的使用

    定义一个Model,让其遵循NSCoding协议,方便我们进行归档数据存储(直接到plist或者NSUserdef...

  • 自定义对象常规的归档和解档

    实现NSCoding协议 使用步骤

  • NSUserDefaults,NSCoding的使用

    NSUserDefaults简介: NSUserDefaults本身是一个单例,在整个程序中只有一个实例对象,它是...

  • Swift class和struct的解归档

    NSCoding 这种方式是OC中就有的,比较老的方式,并且使用限制是只能是calss,然后实现NSCoding,...

  • NSCoding

    使用场景: 将对象存储成文件,当需要的时候随时可以调用 要求: 遵守NSCoding协议 NSCoding相关的类...

  • iOS NSCoding 与 NSSecureCoding

    NSCoding 简介NSCoding是把数据存储在iOS和Mac OS上的一种极其简单和方便的方式,它把模型对象...

  • iOS_NSCoding与NSSecureCoding

    NSCoding NSCoding是把数据存储在iOS和Mac OS上的一种极其简单和方便的方式,它把模型对象直接...

  • NSCoding、NSSecureCoding、NSCopyin

    NSCoding 存与取 NSCoding是把数据存储在iOS和Mac OS上的一种极其简单和方便的方式,它把模型...

网友评论

      本文标题:NSCoding的简单使用

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