一、runtime实现通用copy

如果自定义类的子类,模型套模型你真的会copy吗,小心有坑。

copy需要自定义类继承NSCopying协议

#import <objc/runtime.h>

- (id)copyWithZone:(NSZone *)zone {

    id obj = [[[self class] allocWithZone:zone] init];
Class class = [self class];
while (class != [NSObject class]) {
unsigned int count;
Ivar *ivar = class_copyIvarList(class, &count);
for (int i = ; i < count; i++) {
Ivar iv = ivar[i];
const char *name = ivar_getName(iv);
NSString *strName = [NSString stringWithUTF8String:name];
//利用KVC取值
id value = [[self valueForKey:strName] copy];//如果还套了模型也要copy呢
[obj setValue:value forKey:strName];
}
free(ivar); class = class_getSuperclass(class);//记住还要遍历父类的属性呢
}
return obj;
}

二、runtime实现通用归档解档

归档解档需要自定义类继承NSCoding协议

#import <objc/runtime.h>

#pragma mark - 归档、解档
- (void)encodeWithCoder:(NSCoder *)encoder { Class class = [self class];
while (class != [NSObject class]) {
unsigned int count;
Ivar *ivar = class_copyIvarList(class, &count);
for (int i = ; i < count; i++) {
Ivar iv = ivar[i];
const char *name = ivar_getName(iv);
NSString *strName = [NSString stringWithUTF8String:name];
//利用KVC取值
id value = [self valueForKey:strName];
[encoder encodeObject:value forKey:strName];
}
free(ivar); class = class_getSuperclass(class);//记住还要遍历父类的属性呢
}
} - (id)initWithCoder:(NSCoder *)decoder {
self = [super init];
if (self) { Class class = [self class];
while (class != [NSObject class]) {
unsigned int count = ;
//获取类中所有成员变量名
Ivar *ivar = class_copyIvarList(class, &count);
for (int i = ; i < count; i++) {
Ivar iva = ivar[i];
const char *name = ivar_getName(iva);
NSString *strName = [NSString stringWithUTF8String:name];
//进行解档取值
id value = [decoder decodeObjectForKey:strName];
//利用KVC对属性赋值
[self setValue:value forKey:strName];
}
free(ivar); class = class_getSuperclass(class);//记住还要遍历父类的属性呢
}
}
return self;
}

三、NSUserDefaults存储自定义对象

//1.自定义类继承NSCoding协议,并实现归档解档,前面介绍过了,不多说

//2.将自定义对象转NSData
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:student]; //3.存到NSUserDefaults
[[NSUserDefaults standardUserDefaults] setObject:data forKey:@"myStudent"];
[[NSUserDefaults standardUserDefaults] synchronize];//这句要写,很多人都忘了 //4.存数组,数组中包含自定义对象
[dataArray addObject:data];//这个data是第2步归档得到的data //5.NSUserDefaults只能存不可变数组,不要忘了转换成不可变
NSArray * array = [NSArray arrayWithArray:dataArray];
[[NSUserDefaults standardUserDefaults] setObject:array forKey:@"students"];

四、NSUserDefaults中读取归档的自定义对象

NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:@"myStudent"];
Student *student = [NSKeyedUnarchiver unarchiveObjectWithData:data];

iOS 自定义对象及子类及模型套模型的拷贝、归档存储的通用代码的更多相关文章

  1. iOS 自定义对象转NSDictionary

    我们在向后台Post数据的时候,常常需要把某个对象作为参数,比如在AF的框架中,我们进行Post时,其中的para参数就是需要NSdictionary的 Alamofire.request(.POST ...

  2. iOS开发——UI进阶篇(十一)应用沙盒,归档,解档,偏好设置,plist存储,NSData,自定义对象归档解档

    1.iOS应用数据存储的常用方式XML属性列表(plist)归档Preference(偏好设置)NSKeyedArchiver归档(NSCoding)SQLite3 Core Data 2.应用沙盒每 ...

  3. JavaScript---网络编程(5)-自定义对象Json、Dom模型概念讲解

    这节博客主要讲解Dom模型概念~和JSON的简单介绍 首先,还是先上out.js的代码: function println(param){ document.write(param+"< ...

  4. Keras处理已保存模型中的自定义层(或其他自定义对象)

    如果要加载的模型包含自定义层或其他自定义类或函数,则可以通过 custom_objects 参数将它们传递给加载机制: from keras.models import load_model # 假设 ...

  5. ios深拷贝,浅拷贝,拷贝自定义对象的简单介绍(转)

    copy语法的目的:改变副本的时候,不会影响到源对象: 深拷贝:内容拷贝,会产生新的对象.新对象计数器置为1,源对象计数器不变. 浅拷贝:指针拷贝,不会产生新的对象.源对象计数器+1. 拷贝有下面两个 ...

  6. ios存储 plist 偏好设置 自定义对象存储

    1,plist Plist注意:不能存储自定义对象 Plist:数组和字典,  如何判断一个对象能不能使用Plist,就看下有没有writeToFile 获取应用的文件夹(应用沙盒) NSString ...

  7. iOS 深拷贝、浅拷贝、自定义对象拷贝简介

    copy语法的目的:改变副本的时候,不会影响到源对象: 深拷贝:内容拷贝,会产生新的对象.新对象计数器置为1,源对象计数器不变. 浅拷贝:指针拷贝,不会产生新的对象.源对象计数器+1. 拷贝有下面两个 ...

  8. IOS 如何持久化自定义对象 2014-08-01 01:38

    如果持久话自定义对象 那么这个对象一定要遵循 NSCoding 协议 并实现编解码:然后再将编解码后的数据 NSKeyedArchiver 到NSData中   @interface NSKeyAnd ...

  9. 如何理解iOS的“对象等同性”

    在iOS开发过程中,我们经常需要用到等同性来判断两个对象是否相等,通常我们会使用==来判断,但是这样比较出来的结果可能不是我们期望的:所以,一般我们会使用NSObject协议声明的isEqual方法来 ...

随机推荐

  1. 【Android XML】Android XML 转 Java Code 系列之 style(3)

    最近一个月把代码重构了一遍, 感觉舒服多了, 但总体开发进度没有变化.. 今天聊聊把style属性转换成Java代码的办法 先说结论: 引用系统style是无法完美的实现的, 我们如果有写成Java代 ...

  2. java===java基础学习(4)---字符串操作

    java中的字符串操作和python中的大致相同,需要熟悉的就是具体操作形式. 关于具体api的使用,详见:java===字符串常用API介绍(转) package testbotoo; public ...

  3. An unhandled exception of type 'System.TypeInitializationException' occurred in System.ServiceModel.dll

    异常“ An unhandled exception of type 'System.TypeInitializationException' occurred in System.ServiceMo ...

  4. Lodash使用示例(比较全)

    <html> <head> <meta name="viewport" content="width=device-width" ...

  5. springmvc中输出字符串

    /** * 输出文字 * @param response * @param s */ public static void responseOut(HttpServletResponse respon ...

  6. FineReport——JS二次开发(局部刷新)

    在FR中,可以通过在form表单设置多个报表模板,然后通过对某一模板刷新实现局部刷新的功能,在cpt模板中,由于只存在一个模板,所以无法实现局部刷新. 其实,最好的局部刷新办法是自定义一个页面,然后添 ...

  7. POJ-2594

    Treasure Exploration Time Limit: 6000MS   Memory Limit: 65536K Total Submissions: 7035   Accepted: 2 ...

  8. Monty Hall悖论

    Monty Hall悖论又称为蒙提·霍尔悖论.三门问题.Monty Hall是上个世纪60年代,电视游戏节目“Let's Make a Deal”的主持人,这个悖论便是以他的名字来命名的.节目的规则是 ...

  9. springboot+maven+thymeleaf配置实战demo

    本案例使用thymeleaf,与springboot配置使用.thymeleaf是一种模板语言,可以动态或者静态显示文本内容. 1 .项目结构 2.构建springboot项目 通过idea的new ...

  10. CentOS7安装和配置vsftpd

    (1)vsftpd基本介绍 作用:实现文件共享 1)vsftpd两种模式 主动模式 所谓主动模式,指的是FTP服务器"主动"去连接客户端的数据端口来传输数据,其过程具体来说就是:客 ...