资讯专栏INFORMATION COLUMN

关于常见的协议-归/解档、深/浅拷贝

liuchengxu / 1139人阅读

摘要:相反,把磁盘里的数据变成对象,则称为解档。协议声明了一个可被归档与解档的类所必须实现的方法。创建一个目标类的对象,通过指针完成对对象的拷贝工作。此协议仅声明了一个方法,但是可变的拷贝常常是通过调起。

NSCoding

很多时候,我们需要将我们的处于内存里的对象保存到磁盘里,方便下次使用这个对象。其中,这个保存过程叫做归档-archive。相反,把磁盘里的数据变成对象,则称为解档-unarchive。

而unarchive中包含把二进制数据转化成对象的过程,称为序列化;相反,把一个对象变成磁盘里的文件这个归档过程中,对象转变成二进制数据这个过程,就就反序列化。

或者这样理解:序列化是把看似凌乱的二进制数据变成有序的结构体(内存里的对象其实就是以结构体的形式存在的),反序列化就是把有序的结构体对象变成看似凌乱的二进制数据。

NSCoding协议声明了一个可被归档与解档的类所必须实现的方法。遵循这个协议就必须实现里边的两个个方法:

// 归档
- (void)encodeWithCoder:(NSCoder *)encoder
  
// 解档
- (instancetype)initWithCoder:(NSCoder *)decoder

通常,它们是这么实现的:

// 归档
- (void)encodeWithCoder:(NSCoder *)coder {
    [coder encodeObject:self.firstName forKey:ASCPersonFirstName];// object -> 
    [coder encodeObject:self.lastName forKey:ASCPersonLastName];
    [coder encodeFloat:self.height forKey:ASCPersonHeight];// float -> 注意区别!
}

// 解档
- (id)initWithCoder:(NSCoder *)coder {
  self = [super init];
  if (self) {
      _firstName = [coder decodeObjectForKey:ASCPersonFirstName]; // -> object
      _lastName = [coder decodeObjectForKey:ASCPersonLastName];
      _height = [coder decodeFloatForKey:ASCPersonHeight]; // -> float 注意区别!
  }
  
  return self;
}

另外,需要归档 、解档的时候通常这么写:

// 1.归档
MyObject *object = [MyObject new];
NSString * documentDir= [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSString * archivePath = [documentDir stringByAppendingPathComponent:@"objFile"];

[NSKeyedArchiver archiveRootObject:object toFile:archivePath];    

// 2.解档
MyObject *object1 = [NSKeyedUnarchiver unarchiveObjectWithFile:archivePath];
NSCopying/NSMutableCopying NSCopying

这个协议主要是用于实现自定义对象的拷贝,且是不可变的拷贝。里边也就只有一个必须实现的方法:

// 浅拷贝/指针拷贝
- (id)copyWithZone:(NSZone *)zone

你要想一个自定义的对象能得到合适的拷贝,那么你得遵循这个协议并实现这个方法,然后 自定义的类对象[aCustomInstance copy] 才可能正确工作。

ps:对象调用copy方法,其实就是简单的调用了copyWithZone:方法。

一般的实现可能是:

// 情况1-父类没有实现copyWithZone:
@interface MyBaseObject : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, strong) NSDate *date;
@property (nonatomic, assign) NSInteger value;

- (id)copyWithZone:(NSZone *)zone {
    //MyObject *newObject = [MyObject new];//这种做法的问题就是:当被子类调用时,返回的对象会有问题。我们希望返回的是-目标对象。
      MyObject *newObject = [[self class new]];// 创建一个目标类的对象,通过newObject指针完成对MyObject对象的拷贝工作。
      if(newObject){
      newObject.name = _name;
        newObject.date = _date;
        newObject.value = _value;  
    }
  
    return newObject;
}

/*===========================================================================*/

// 情况2 - 父类实现了 copyWithZone:
@interface MySubObject : MyBaseObject
@property (nonatomic, copy)NSString *property1;
@property (nonatomic, copy)NSString *property2;
@end

- (id)copyWithZone:(NSZone *)zone {
  MySubObject *newObject = [super copyWithZone:zone];
  if (newObject){//完成本类中自定义属性(实例变量)的拷贝工作。
    newObject.property1 = _property1;
    newObject.property2 = _property2;
  }
  
  return newObject;
}

当MyObject类里又包含其它自定义的类,可变数组,不可变数组等情况时,则更为复杂,需要根据类设计初衷来考虑这个方法的实现。

NSMutableCopying

此协议仅声明了一个方法:mutableCopyWithZone: ,但是可变的拷贝常常是通过 mutableCopy 调起。这个mutableCopy 方法是在所有的 NSObject 类中定义,且只是简单的调用 mutableCopyWithZone: 而已。

如NSCopying协议一样,如果父类实现了NSMutableCopying协议,那么在实现子类的mutableCopyWithZone: 方法时,需先调用父类的 mutableCopyWithZone: 。

小结

感觉NSCopying协议平时在开发中使用的机会还是比较少(咳咳,其实我只是在文档、笔试题里或者技术博客里见到过一些介绍,或者常见的系统内置类型,如:NSString/NSMutableString、NSArray/NSMutableArray等)。所以具体的实战可能最好比较或者参考一下这些已有的类或者接口。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/16417.html

相关文章

  • 前端基础汇总

    摘要:及相关问题数据类型函数中指向原型作用域闭包面向对象对象创建模式继承严格模式与对象转换的方法添加属性,根据原型创建区别新特性解构赋值简化对象写法剪头函数三点运算符模板字符串形参默认值异步过程深拷贝与浅拷贝赋值与浅拷贝的区别浅拷贝的几种方法实现 js及es相关问题 数据类型函数中this指向——————原型作用域闭包——————面向对象对象创建模式继承——————Es5严格模式Json与j...

    2json 评论0 收藏0
  • 前端基础汇总

    摘要:及相关问题数据类型函数中指向原型作用域闭包面向对象对象创建模式继承严格模式与对象转换的方法添加属性,根据原型创建区别新特性解构赋值简化对象写法剪头函数三点运算符模板字符串形参默认值异步过程深拷贝与浅拷贝赋值与浅拷贝的区别浅拷贝的几种方法实现 js及es相关问题 数据类型函数中this指向——————原型作用域闭包——————面向对象对象创建模式继承——————Es5严格模式Json与j...

    laznrbfe 评论0 收藏0
  • 一篇文章彻底说清JS拷贝/拷贝

    摘要:一篇文章彻底说清的深拷贝浅拷贝这篇文章的受众第一类业务需要急需知道如何深拷贝对象的开发者。这篇文章分享的目的更多还是希望用一篇文章整理清楚深浅拷贝的含义递归实现思路以及小伙伴们如果使用了这种黑科技一定要清楚这样写的优缺点。 一篇文章彻底说清JS的深拷贝and浅拷贝 这篇文章的受众 第一类,业务需要,急需知道如何深拷贝JS对象的开发者。 第二类,希望扎实JS基础,将来好去面试官前秀操作...

    J4ck_Chan 评论0 收藏0
  • 一篇文章彻底说清JS拷贝/拷贝

    摘要:一篇文章彻底说清的深拷贝浅拷贝这篇文章的受众第一类业务需要急需知道如何深拷贝对象的开发者。这篇文章分享的目的更多还是希望用一篇文章整理清楚深浅拷贝的含义递归实现思路以及小伙伴们如果使用了这种黑科技一定要清楚这样写的优缺点。 一篇文章彻底说清JS的深拷贝and浅拷贝 这篇文章的受众 第一类,业务需要,急需知道如何深拷贝JS对象的开发者。 第二类,希望扎实JS基础,将来好去面试官前秀操作...

    lakeside 评论0 收藏0
  • 一篇文章彻底说清JS拷贝/拷贝

    摘要:一篇文章彻底说清的深拷贝浅拷贝这篇文章的受众第一类业务需要急需知道如何深拷贝对象的开发者。这篇文章分享的目的更多还是希望用一篇文章整理清楚深浅拷贝的含义递归实现思路以及小伙伴们如果使用了这种黑科技一定要清楚这样写的优缺点。 一篇文章彻底说清JS的深拷贝and浅拷贝 这篇文章的受众 第一类,业务需要,急需知道如何深拷贝JS对象的开发者。 第二类,希望扎实JS基础,将来好去面试官前秀操作...

    big_cat 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<