iOS数据持久化之二——归档与设计可存储化的数据模型基类(二)

简介: iOS数据持久化之二——归档与设计可存储化的数据模型基类

(3)进行自定义对象的归档


       上面介绍中有提到,原则上,任何遵守了NSCoding协议的类都可以进行归档操作,那么对于我们自定义的对象,我们该如何来做呢?


首先,我们新建一个类:


仿照上面的例子,我们写一个这样的类:


@interface MyObject : NSObject

@property(nonatomic,strong)NSString * name;

@property(nonatomic,assign)int age;

@end


对其进行归档:


   //进行归档

   MyObject * obj = [[MyObject alloc]init];

   obj.name = @"jaki";

   obj.age = 24;

   NSData * data =  [NSKeyedArchiver archivedDataWithRootObject:obj];

   //进行解档

   MyObject * obj2 = [NSKeyedUnarchiver unarchiveObjectWithData:data];

   NSLog(@"\nname:%@\nage:%d",obj2.name,obj2.age);


直接运行,程序会崩溃掉,打印如下:

image.png



可以看出,正是我们前边说过的,必须遵守归档协议的对象,才可以被归档,我们在MyObject类中实现如下两个方法:


//解档方法

- (instancetype)initWithCoder:(NSCoder *)coder

{

   if (self=[super init]) {

       _name = [coder decodeObjectForKey:@"name"];

       _age = [coder decodeIntForKey:@"age"];

   }

   return self;

}


//归档方法

- (void)encodeWithCoder:(NSCoder *)coder

{

   [coder encodeObject:_name forKey:@"name"];

   [coder encodeInt:_age forKey:@"age"];

}


添加了上面两个方法,我们自定义的对象就可以自由归档存取,并可以写入本地,非常cool吧。


三、设计可以归档存取的数据模型基类


1、动机与初衷


       通过上面对归档的介绍,我们可以发现归档一个十分有潜力的应用:可以自由存取自定义的数据对象。这个特性的优势是毫无疑问的,除了可以使我们的数据用起来更加方便,无需多次解析数据外,安全性也更好。但是也带来了一个缺陷,每个类都需要实现NSCoding中的两个方法是十分繁琐的,并且类越复杂,这个步骤越繁琐,如果在之后的修改和优化中类做了改变,相应的方法也要做改变,这将增加很大的工作量并且埋下潜在bug的风险。


       所以我们会想,能否设计一个这样的model基类,来使需要存储的model都继承于它,使我们的model不需要实现NSCoding方法的同时可以支持归档呢,通过runtime和OC语言特性的一些小技巧,我们是可以做到的。


2、基类模型的设计


       我们新建一个BaseModel类,核心方法如下:


//归档与解归档的方法

- (instancetype)initWithCoder:(NSCoder *)coder

{

   self = [super init];

   if (self) {

       //获取所有属性

       NSArray * porpertyArray = [self getAllPropertys];

       for (NSString * name in porpertyArray) {

           //去掉属性名前面的_

           NSString * key = [name substringFromIndex:1];

           //约定好的键值对 c+key

           [self setValue:[coder decodeObjectForKey:[NSString stringWithFormat:@"c%@",key]] forKey:key];

       }

   }

   return self;

}

- (void)encodeWithCoder:(NSCoder *)coder

{

 

   //获取所有属性

   NSArray * porpertyArray = [self getAllPropertys];

   for (NSString * name in porpertyArray) {

       //去掉属性名前面的_

       NSString * key = [name substringFromIndex:1];

       //约定好的键值对 c+key

       [coder encodeObject:[self valueForKey:key] forKey:[NSString stringWithFormat:@"c%@",key]];

   }

}

//获取model所有属性

-(NSArray *)getAllPropertys{

   NSMutableArray * array = [[NSMutableArray alloc]init];

 

   unsigned int * count = malloc(sizeof(unsigned int));

   //调用runtime的方法

   //Ivar:方法返回的对象内容对象,这里将返回一个Ivar类型的指针

   //class_copyIvarList方法可以捕获到类的所有变量,将变量的数量存在一个unsigned int的指针中

   Ivar * mem = class_copyIvarList([self class], count);

   //进行遍历

   for (int i=0; i< *count ; i++) {

       //通过移动指针进行遍历

       Ivar var = * (mem+i);

       //获取变量的名称

       const char * name = ivar_getName(var);

       NSString * str = [NSString stringWithCString:name encoding:NSUTF8StringEncoding];

       [array addObject:str];

   }

   //释放内存

   free(count);

   //注意处理野指针

   count=nil;

   return array;

}


通过这样的一个runtime机制,我们可以很方便的是新建的model继承于这个基类,无需其他处理直接支持归档,修改与优化都不受影响。


四、为志同道合的朋友分享


       这个model集成在了我的一个开源的开发框架中,当然,那里面也综合和许多许多这样方便开发者使用的功能,如果你感兴趣,可以在https://github.com/ZYHshao/YHBaseFoundationTest上面看到。如果你发现了一些bug或者可以添加或者优化的地方,请务必告知我,十分你感谢。QQ:316045346

目录
相关文章
|
1月前
|
开发框架 前端开发 Android开发
Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势
本文深入探讨了 Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势。这对于实现高效的跨平台移动应用开发具有重要指导意义。
166 4
|
7月前
|
JSON JavaScript 安全
iOS应用程序数据保护:如何保护iOS应用程序中的图片、资源和敏感数据
iOS应用程序数据保护:如何保护iOS应用程序中的图片、资源和敏感数据
71 1
|
7月前
|
存储 iOS开发 开发者
使用克魔助手进行iOS数据抓包和HTTP抓包的方法详解
使用克魔助手进行iOS数据抓包和HTTP抓包的方法详解
114 0
|
4月前
|
iOS开发 开发者
iOS平台RTMP|RTSP播放器如何实时回调YUV数据
我们在做RTMP、RTSP播放器的时候,有开发者需要自己处理拉取到的YUV数据,做二次分析之用,为此,我们做了以下的设计:InitPlayer之后,再调用SmartPlayerStart()接口之前,设置yuv数据回调即可。
|
7月前
|
Java iOS开发
iOS的数据序列化(又称持久化)的两类使用方式
iOS的数据序列化(又称持久化)的两类使用方式
72 0
|
7月前
|
移动开发 小程序 API
uniapp通过蓝牙传输数据 (ios)
uniapp通过蓝牙传输数据 (ios)
371 1
|
7月前
|
JSON JavaScript 安全
iOS 应用程序数据保护:如何保护 iOS 应用程序中的图片、资源和敏感数据
iOS 应用程序数据保护:如何保护 iOS 应用程序中的图片、资源和敏感数据
|
7月前
|
Web App开发 网络安全 Android开发
🚀2023最新版克魔助手抓包教程(9) - 克魔助手 IOS 数据抓包
在移动应用程序的开发中,了解应用程序的网络通信是至关重要的。数据抓包是一种很好的方法,可以让我们分析应用程序的网络请求和响应,了解应用程序的网络操作情况。克魔助手是一款非常强大的抓包工具,可以帮助我们在 Android 和 iOS 平台上进行数据抓包。本篇博客将介绍如何使用克魔助手在 iOS 平台上进行数据抓包。
|
7月前
|
Java 开发工具 Android开发
SLS:使用 OTel 官方 SDK 采集 Android、iOS Trace 数据实践
本文介绍了使用 OTel 官方 SDK 采集 Android、iOS Trace 数据实践。
497 7
SLS:使用 OTel 官方 SDK 采集 Android、iOS Trace 数据实践
|
1月前
|
开发框架 前端开发 Android开发
安卓与iOS开发中的跨平台策略
在移动应用开发的战场上,安卓和iOS两大阵营各据一方。随着技术的演进,跨平台开发框架成为开发者的新宠,旨在实现一次编码、多平台部署的梦想。本文将探讨跨平台开发的优势与挑战,并分享实用的开发技巧,帮助开发者在安卓和iOS的世界中游刃有余。