利用objc runtime 和 KVC 对自定义对象归档解档

       在开发过程中对自定义对象数据进行归档解档时候需要实现两个方法: encodeWithCoder和initWithEncoder。encodeWithCoder就是编码,initWithCoder就是解码。比如下面我自定义对象MyModel进行归档和解档。

     

- (void)encodeWithCoder:(NSCoder *)aCoder{
    [aCoder encodeObject:[NSNumber numberWithInt:self.custId] forKey:kCUSTIDKey];
    [aCoder encodeObject:[NSNumber numberWithInt:self.custStatusId] forKey:kCUSTSTATUSKey];
    [aCoder encodeObject:self.phoneName forKey:kPHONEKey];
    [aCoder encodeObject:self.houseName forKey:kHOUSENUMKey];
    [aCoder encodeObject:self.nickName forKey:kNICKNAMEKey];
}

- (id)initWithCoder:(NSCoder *)aDecoder{
    self = [super init];
    if (self) {
        self.custId = [[aDecoder decodeObjectForKey:kCUSTIDKey] intValue];
        self.custStatusId = [[aDecoder decodeObjectForKey:kCUSTSTATUSKey] intValue];
        self.phoneName = [aDecoder decodeObjectForKey:kPHONEKey];
        self.houseName = [aDecoder decodeObjectForKey:kHOUSENUMKey];
        self.nickName = [aDecoder decodeObjectForKey:kNICKNAMEKey];
    }
    return self;
    
}

当对象的属性很多的时候,我们这样写简直是太繁琐了,有没有一种简便的方法少些重复的代码呢,答案当然有,利用objc runtime动态的获取对象的属性,并且采用KVC(key-value-coding)的方式实现归档和解档,比如:
/*
 *   Objective-C运行时库提供了非常便利的方法获取其对象运行时所属类及其所有成员变量,
 *   并通过KVC进行值的存取,那么或者可以这样objc/runtime+KVC
 */
    

- (void)encodeWithCoder:(NSCoder *)aCoder{
    unsigned int count;
    Ivar *ivar = class_copyIvarList([MyModel 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];
        [aCoder encodeObject:value forKey:strName];
    }
    free(ivar);
}

- (id)initWithCoder:(NSCoder *)aDecoder{
    self = [super init];
    if (self) {
        unsigned int count = 0;
        //获取类中所有成员变量名
        Ivar *ivar = class_copyIvarList([MyModel 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 = [aDecoder decodeObjectForKey:strName];
            //利用KVC赋值
            [self setValue:value forKey:strName];
        }
        free(ivar);
    }
    return self;

}

下面具体来看一个实例:

1、MyModel.h

//
//  MyModel.h
//  UseKVO
//
//  Created by T-MAC on 15/4/19.
//  Copyright (c) 2015年 T-MAC. All rights reserved.
//

#import <Foundation/Foundation.h>
#define kCUSTIDKey @"CUSTIDKey"
#define kCUSTSTATUSKey @"CUSTSTATUSKey"
#define kNICKNAMEKey @"NICKNAMEKey"
#define kHOUSENUMKey @"HOUSENUMKey"
#define kPHONEKey @"PHONEKey"

@interface MyModel : NSObject<NSCoding>{
    int custId;
    int custStatusId;
    NSString *phoneName;
    NSString *nickName;
    NSString *houseName;
}

@property (nonatomic,assign) int custId;
@property (nonatomic,assign) int custStatusId;
@property (nonatomic,strong) NSString *phoneName;
@property (nonatomic,strong) NSString *nickName;
@property (nonatomic,strong) NSString *houseName;

+ (id)initWithCustId:(int)custId withStatusId:(int)statusId withPhoneName:(NSString *)phone withNickName:(NSString *)nickName withHouseName:(NSString *)houseName;

- (NSString *)description;


@end

2、MyModel.m

//
//  MyModel.m
//  UseKVO
//
//  Created by T-MAC on 15/4/19.
//  Copyright (c) 2015年 T-MAC. All rights reserved.
//

#import "MyModel.h"
#import <objc/runtime.h>

@implementation MyModel

@synthesize custId;
@synthesize custStatusId;
@synthesize phoneName;
@synthesize houseName;
@synthesize nickName;


+ (id)initWithCustId:(int)custId withStatusId:(int)statusId withPhoneName:(NSString *)phone withNickName:(NSString *)nickName withHouseName:(NSString *)houseName{
    MyModel *mode = [[self alloc] init];
    if (mode) {
        mode.custId = statusId;
        mode.custStatusId = statusId;
        mode.phoneName = phone;
        mode.nickName = nickName;
        mode.houseName = houseName;
    }
    return mode;
}

/*
 *不使用runtime+kvc
 */
//- (void)encodeWithCoder:(NSCoder *)aCoder{
//    [aCoder encodeObject:[NSNumber numberWithInt:self.custId] forKey:kCUSTIDKey];
//    [aCoder encodeObject:[NSNumber numberWithInt:self.custStatusId] forKey:kCUSTSTATUSKey];
//    [aCoder encodeObject:self.phoneName forKey:kPHONEKey];
//    [aCoder encodeObject:self.houseName forKey:kHOUSENUMKey];
//    [aCoder encodeObject:self.nickName forKey:kNICKNAMEKey];
//}
//
//- (id)initWithCoder:(NSCoder *)aDecoder{
//    self = [super init];
//    if (self) {
//        self.custId = [[aDecoder decodeObjectForKey:kCUSTIDKey] intValue];
//        self.custStatusId = [[aDecoder decodeObjectForKey:kCUSTSTATUSKey] intValue];
//        self.phoneName = [aDecoder decodeObjectForKey:kPHONEKey];
//        self.houseName = [aDecoder decodeObjectForKey:kHOUSENUMKey];
//        self.nickName = [aDecoder decodeObjectForKey:kNICKNAMEKey];
//    }
//    return self;
//    
//}



/*
 *   Objective-C运行时库提供了非常便利的方法获取其对象运行时所属类及其所有成员变量,
 *   并通过KVC进行值的存取,那么或者可以这样objc/runtime+KVC
 */
    

- (void)encodeWithCoder:(NSCoder *)aCoder{
    unsigned int count;
    Ivar *ivar = class_copyIvarList([MyModel 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];
        [aCoder encodeObject:value forKey:strName];
    }
    free(ivar);
}

- (id)initWithCoder:(NSCoder *)aDecoder{
    self = [super init];
    if (self) {
        unsigned int count = 0;
        //获取类中所有成员变量名
        Ivar *ivar = class_copyIvarList([MyModel 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 = [aDecoder decodeObjectForKey:strName];
            //利用KVC赋值
            [self setValue:value forKey:strName];
        }
        free(ivar);
    }
    return self;

}


- (NSString *)description{
    NSString *resStr = [NSString stringWithFormat:@"self.custid = %d,self.custStatusId = %d,self.phonename = %@,self.nickname = %@,self.housename = %@",self.custId,self.custStatusId,self.phoneName,self.nickName,self.houseName];
    return resStr;
}
@end

3、存储自定义对象到文件验证归档、解档是否成功

    //1.创建自定义对象
    MyModel *mode = [MyModel initWithCustId:1 withStatusId:100 withPhoneName:@"apple" withNickName:@"json" withHouseName:@"white house"];
    
    //2.获取文件路径
    NSString *docPath=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject];
    NSString *path=[docPath stringByAppendingPathComponent:@"person.yangyang"];
    
    //3.写入文件---归档
    [NSKeyedArchiver archiveRootObject:mode toFile:path];
    
    //4.取出文件---接档
    MyModel *retMode = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
   
    NSLog(@"retMode === %@",retMode);



从打印的结果看到,采用此方法成功的实现了归档和解档。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: objc app架构是一种基于Objective-C语言开发的应用程序架构。在这种架构,应用程序的主要组成部分是由Objective-C编写的对象,这些对象封装了应用程序的业务逻辑和功能。 在objc app架构,主要包含以下几个关键的组件: 1. 模型(Model):模型是应用程序的数据和业务逻辑的核心。在objc app架构,模型通常由Objective-C类实现,用于封装数据和处理相关的业务逻辑。 2. 控制器(Controller):控制器负责协调模型和视图之间的交互。它接收用户的输入,并将其传递给模型进行处理,然后更新视图以显示结果。控制器通常是Objective-C类,用于处理应用程序的逻辑控制和事件处理。 3. 视图(View):视图是应用程序的用户界面的可视化表示。它负责显示模型的数据,并将用户的输入传递给控制器进行处理。在objc app架构,视图通常是由UIKit或Cocoa Touch框架提供的界面元素,如按钮、标签、文本框等。 通过以上三个组件的协同工作,objc app架构实现了应用程序的分层架构,将数据、逻辑和界面分离开来,提高了代码的可维护性和复用性。此外,objc app架构还支持面向对象编程的特性,如封装、继承和多态,以及设计模式的使用,如MVC(Model-View-Controller)模式,从而进一步提高了应用程序的开发效率和质量。 总而言之,objc app架构是一种基于Objective-C语言的应用程序架构,通过模型、控制器和视图的协同工作,实现了数据、逻辑和界面的分离,提高了应用程序的可维护性和复用性。 ### 回答2: ObjC App架构是iOS应用开发的一种常见的架构模式。它由iOS开发者王巍所提出,旨在提供一种清晰、可扩展和易于维护的应用架构。 ObjC App架构的核心思想是将应用分解成相互独立的模块,每个模块负责特定的功能。这些模块之间通过协议和委托进行通信,实现了低耦合和可测试性。常见的模块有View、ViewModel和Model。 View层负责用户界面的展示和用户交互的响应。View层主要由ViewController组成,负责将用户的操作传递给ViewModel,并将ViewModel返回的数据展示给用户。此外,View层还包括了View和ViewModel之间的绑定,实现了双向数据绑定。 ViewModel层是View层和Model层之间的桥梁,负责处理业务逻辑和数据的转换。ViewModel层通常包含了与网络请求、数据解析和数据处理相关的代码。ViewModel将Model层的数据转换成View所需的格式,并将用户的操作转发给Model层。 Model层负责数据的存储和获取。它可以包含网络请求、数据库操作、数据解析等功能。Model层的设计应尽量简单,只关注数据的读写,而不涉及业务逻辑。 通过使用ObjC App架构,我们可以将应用的不同功能模块分解成独立的部件,使得代码更加清晰和易于维护。同时,模块之间低耦合的设计也提高了代码的扩展性和可测试性。此外,ObjC App架构还可以提高多人协作开发的效率,不同团队成员可以专注于各自负责的模块,降低了代码冲突和合并的难度。 总的来说,ObjC App架构是一种优秀的iOS应用架构模式,它通过分解应用的功能模块,提供了清晰、可扩展和易于维护的代码结构。这种架构模式在iOS开发得到了广泛应用,并为开发者提供了更好的开发体验和效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值