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

一、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 = 0; 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 = 0; 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 = 0;
            //获取类中所有成员变量名
            Ivar *ivar = class_copyIvarList(class, &count);
            for (int i = 0; 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];

原文地址:https://www.cnblogs.com/zhanglinfeng/p/8418407.html

时间: 2024-10-01 12:25:04

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

iOS自定义对象保存到本地文件

我是将聊天记录存到本地,里边用到了自定义的对象,把数据转成Data格式存到本地,在转Data格式的时候报错了,这时候需要先将自定义对象进行归档才可以转Data格式.方法如下: 一.在.h文件中声明<NSCoding>协议 二.在.m文件中实现encodeWithCoder和intiWithCoder方法 归档之后就把对象存储到字典或数组里,转成Data格式的,再存储到本地即可. 关于怎么把字典转成Data格式参见我的另一篇文章: 地址:http://blog.csdn.net/miaocuil

iOS-NSUserDefaults缓存自定义对象

转载自:http://my.oschina.net/u/1245365/blog/294449 转载请保留原地址 摘要 NSUserDefaults适合存储轻量级的本地数据,一些简单的数据(NSString类型的)例如密码,网址等,NSUserDefaults肯定是首选,但是如果我们自定义了一个对象,对象保存的是一些信息,这时候就不能直接存储到NSUserDefaults了 NSUserDefaults 存储自定义对象 目录[-] 一.了解NSUserDefaults以及它可以直接存储的类型 二

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

1.iOS应用数据存储的常用方式XML属性列表(plist)归档Preference(偏好设置)NSKeyedArchiver归档(NSCoding)SQLite3 Core Data 2.应用沙盒每个iOS应用都有自己的应用沙盒(应用沙盒就是文件系统目录),与其他文件系统隔离.应用必须待在自己的沙盒里,其他应用不能访问该沙盒应用沙盒的文件系统目录,如下图所示(假设应用的名称叫Layer)模拟器应用沙盒的根路径在: (apple是用户名, 8.0是模拟器版本)/Users/apple/Libra

iOS开发——保存自定义对象数组、字典到文件

在ios中,要保存普通的数组到文件可以直接调用-wirteToFile:atomically:方法写入,并且可以通过NSArray的方法-initWithContentOfFile:来读文件初始化数组.然而,当要保存的数组中存储的数据对象是自定义对象时,就得通过对象归档的方法来实现了,具体来说 一.自定义对象实现归档协议,并实现方法- (id)initWithCoder:和方法- (void)encodeWithCoder: @interface CourseModel : CYZBaseMod

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

这节博客主要讲解Dom模型概念~和JSON的简单介绍 首先,还是先上out.js的代码: function println(param){ document.write(param+"<br/>"); } function print(param){ document.write(param); } 什么是 DOM? DOM 是 W3C(万维网联盟)的标准. DOM 定义了访问 HTML 和 XML 文档的标准: "W3C 文档对象模型 (DOM) 是中立于平台和

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

copy语法的目的:改变副本的时候,不会影响到源对象: 深拷贝:内容拷贝,会产生新的对象.新对象计数器置为1,源对象计数器不变. 浅拷贝:指针拷贝,不会产生新的对象.源对象计数器+1. 拷贝有下面两个方法实现拷贝: - (id)copy; - (id)mutableCopy; 对象要实现copy,必须实现<NSCopying>协议数组,字典,字符串都已经实现了<NSCopying>协议,以下以字符串为例: 1.不可变字符串调用copy实现拷(浅拷贝) NSString *strin

iOS 自定义页面的切换动画与交互动画

在iOS7之前,开发者为了寻求自定义Navigation Controller的Push/Pop动画,只能受限于子类化一个UINavigationController,或是用自定义的动画去覆盖它.但是随着iOS7的到来,Apple针对开发者推出了新的工具,以更灵活地方式管理UIViewController切换. 自定义导航栏的Push/Pop动画 为了在基于UINavigationController下做自定义的动画切换,先建立一个简单的工程,这个工程的rootViewController是一个

iOS自定义转场动画实战讲解

iOS自定义转场动画实战讲解 转场动画这事,说简单也简单,可以通过presentViewController:animated:completion:和dismissViewControllerAnimated:completion:这一组函数以模态视图的方式展现.隐藏视图.如果用到了navigationController,还可以调用pushViewController:animated:和popViewController这一组函数将新的视图控制器压栈.弹栈. 下图中所有转场动画都是自定义的

[iOS基础控件 - 4.2] 字典转模型Model

A.使用字典加载数据的缺点 1.用户自行指定key,容易出错 2.存入.取出都需要key,容易混乱 B.模型 (MVC中的model) 1.字典与模型对比: (1)字典:存储数据,通过字符串类型的key取值(容易写错,写错了key编译器不会报错) (2)模型:存储数据,自定义属性存储数据,其实就类似JavaBean,本质是数据封装 2.实现 (1)定义模型类 1 @interface App : NSObject 2 3 /** 4 copy : NSString 5 strong: 一般对象