NSCopying,NSCoding

476 阅读2分钟

一、NSCoding理解

NSCoder的具体子类使用NSCoder抽象类的接口在内存和其他格式之间转换对象和其他数据值,NSCoder可以提供基本的归档——把对象和数据存储在磁盘上,和分配——在不同进程和线程之间复制对象和其他数据。在Foundation框架中会提供NSCoder具体的子类,如:NSArchiver、NSUnarchiver、NSKeyedArchiver、NSKeyUnarchiver和NSPortCoder。NSCoder具体的子类统一称作:编码器类,他们的实例化对象则成为编码器对象,一个编码器对象如果只编码就称做:编码对象,一个编码器对象如果只解码就称作解码对象。

——概述 ——NSCoder可以操作对象、标量、C数组、结构体和字符串,还有这些类型的指针。它不能操作的类型是那些跨平台执行的变量,例如:union、void *、函数指针和长链表的指针。

——一个编码器对象储存object类型的信息连同object的数据,因此,一个从字节流解码的对象通常跟最初编码的对象是同一个类。然而,一个对象可以在编码的时候改变它的类;这是描述归档文件和序列化的编程指南。

从coder中读取数据,并返回相应的类型对象;即反序列化
-(id)initWithCoder:(NSCoder )coder;

将对象转为二进制流,存储在磁盘中
-(void)encodeWithCoder:(NSCoder )coder;

注:一般对数据存储时,使用归档/解档;对象需要满足NSCoding协议,对它 进行数据编码转化成二进制流,存储于磁盘中;解档是将序列化数据转化成 对象,回调新的对象出来;

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface Person : NSObject

@property (nonatomic,strong) NSString *name;
@property (nonatomic,strong) NSString *userNum;

- (Person *)initWithName:(NSString *)name andUserNum:(NSString *)userNum;

@end

NS_ASSUME_NONNULL_END
#import "Person.h"

@implementation Person

- (Person *)initWithName:(NSString *)name andUserNum:(NSString *)userNum {
    if (self = [super init]) {
        self.name = name;
        self.userNum = userNum;
    }
    return self;
}

- (void)encodeWithCoder:(NSCoder *)aCoder {
    [aCoder encodeObject:self.name forKey:@"name"];
    [aCoder encodeObject:self.userNum forKey:@"userNum"];
}

- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder {// NS_DESIGNATED_INITIALIZER
    if (self = [super init]) {
        self.name = [aDecoder decodeObjectForKey:@"name"] ;
        self.userNum = [aDecoder decodeObjectForKey:@"userNum"];
    }
    return self;
}

@end

截屏2021-06-04 下午5.22.05.png

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface YBNotification : NSObject <NSCopying, NSCoding>

@property (readonly, copy) NSString *name;
@property (nullable, readonly, weak) id object;
@property (nullable, readonly, copy) NSDictionary *userInfo;

- (instancetype)initWithName:(NSString *)name object:(nullable id)object userInfo:(nullable NSDictionary *)userInfo;

@end
#import "YBNotification.h"

//发送通知消息体类
@interface YBNotification ()

@property (copy) NSString *name;
@property (weak) id object;
@property (copy) NSDictionary *userInfo;

@end

@implementation YBNotification

- (instancetype)initWithName:(NSString *)name object:(id)object userInfo:(NSDictionary *)userInfo {
    if (!name || ![name isKindOfClass:[NSString class]]) {
        return nil;
    }
    YBNotification *noti = [YBNotification new];
    noti.name = name;
    noti.object = object;
    noti.userInfo = userInfo;
    return noti;
}
- (id)copyWithZone:(NSZone *)zone {
    YBNotification *model = [[[self class] allocWithZone:zone] init];
    model.name = self.name;
    model.object = self.object;
    model.userInfo = self.userInfo;
    return model;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
    [aCoder encodeObject:self.name forKey:@"name"];
    [aCoder encodeObject:self.object forKey:@"object"];
    [aCoder encodeObject:self.userInfo forKey:@"userInfo"];
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
    if (self = [super init]) {
        self.name = [aDecoder decodeObjectForKey:@"name"];
        self.object = [aDecoder decodeObjectForKey:@"object"];
        self.userInfo = [aDecoder decodeObjectForKey:@"userInfo"];
    }
    return self;
}

@end