iOS平台基于KVC的JSON与数据对象绑定

简介: 版权声明:本文为博主chszs的原创文章,未经博主允许不得转载。 https://blog.csdn.net/chszs/article/details/49872407 iOS平台基于KVC的JSON与数据对象绑定作者:chszs,未经博主允许不得转载。
版权声明:本文为博主chszs的原创文章,未经博主允许不得转载。 https://blog.csdn.net/chszs/article/details/49872407

iOS平台基于KVC的JSON与数据对象绑定

作者:chszs,未经博主允许不得转载。经许可的转载需注明作者和博客主页:http://blog.csdn.net/chszs

在iOS平台上,要操纵JSON数据并不困难,但是,我们还有更简单的解决方案,使用KVC,全称是Key-Value Coding。

假设开发者(你)开发了一款应用,它的数据来自于外部对Web服务,要从Web服务中取回一些JSON数据,数据如下:

{"count": 3, "sum": 9.0, "average": 3.0}

要从服务器中获取数据,需要调用NSJSONSerializationalization的JSONObjectWithData方法,并从解序列化的字典中取回数据,比如:

NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];

NSLog(@"%d", [[dictionary objectForKey:@"count"] intValue]); // prints 3Rd
NSLog(@"%.1f", [[dictionary objectForKey:@"sum"] doubleValue]); // prints 9.0
NSLog(@"%.1f", [[dictionary objectForKey:@"average"] doubleValue]); // prints 3.0

但是,上面的值比较分散,在做应用开发时,或许想与强类型的数据对象直接交互,这样会更加简单。比如,你或许想要创建一个Statistics统计类,来代表通过Web服务返回的数据类型,如下:

@interface Statistics : NSObject

@property (nonatomic) int count;
@property (nonatomic) double sum;
@property (nonatomic) double average;

@end

然后可以从字典中提取值来填充以上的对象:

Statistics *statistics = [[Statistics alloc] init];

statistics.count = [[dictionary objectForKey:@"count"] intValue];
statistics.sum = [[dictionary objectForKey:@"sum"] doubleValue];
statistics.average = [[dictionary objectForKey:@"average"] doubleValue];

为了让事情更简单,避免代码重复,可以把这段代码放在Statistics类的初始化中:

- (instancetype)initWithDictionary:(NSDictionary *)dictionary {
    self = [super init];
    if (self) {
        self.count = [[dictionary objectForKey:@"count"] intValue];
        self.sum = [[dictionary objectForKey:@"sum"] doubleValue];
        self.average = [[dictionary objectForKey:@"average"] doubleValue];
    }
    return self;
}

代码绑定JSON响应到Statistics实例,如下:

Statistics *statistics = [[Statistics alloc] initWithDictionary:dictionary];

在任何情况下,你都可以使用此强类型的数据对象的属性来访问从服务器返回的数据:

NSLog(@"%d", statistics.count); // prints 3
NSLog(@"%.1f", statistics.sum); // prints 9.0
NSLog(@"%.1f", statistics.average); // prints 3.0

上面的代码工作正常,而且把JSON数据映射到强类型的数据对象是非常适合的方法。

但是,还有更简单的解决方案:KVC。NSObject的setValuesForKeysWithDictionary:方法可用于将给定字典上所有的值自动映射到对象的属性。使用这种方法,initWithDictionary:方法简化如下:

- (instancetype)initWithDictionary:(NSDictionary *)dictionary {
    self = [super init];
    if (self) {
        [self setValuesForKeysWithDictionary:dictionary];
    }
    return self;
}

无需手动映射字典到项到属性值中,使用适合的名字和类型来声明属性就足够了,下面的代码中Swift中工作良好:

class Statistics: NSObject {
    var count: Int = 0
    var sum: Double = 0
    var average: Double = 0
    init(dictionary: [String:AnyObject]) {
        super.init()
        setValuesForKeysWithDictionary(dictionary);
    }
}

此外,如果你需要自定义属性名或属性值的分配,那么可以简单的重写setValue:forKey:方法。比如,假设服务器以不同的名字来引用平均属性:

{"count": 3, "sum": 9.0, "mean": 3.0}

可以重写setValue:forKey:方法,确保值能正确的映射到属性中:

- (void)setValue:(id)value forKey:(NSString *)key {
    if ([key isEqual:@"mean"]) {
        key = @"average";
    }
    [super setValue:value forKey:key];
}

最后,你可以使用KVC来忽略你不想要的值。比如,假设服务器的响应还包含了名为“median”的属性:

{"count": 3, "sum": 9.0, "average": 3.0, "median": 3.0}

由于Statistics类没有定义“Median”属性,那么setValuesForKeysWithDictionary:方法会抛出NSUnknownKeyException异常。要避免抛出此异常,可以简单的重写setValue:forUndefinedKey::方法。

- (void)setValue:(id)value forUndefinedKey:(NSString *)key {
    // No-op
}
目录
相关文章
|
26天前
|
开发框架 前端开发 Android开发
Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势
本文深入探讨了 Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势。这对于实现高效的跨平台移动应用开发具有重要指导意义。
104 4
|
2月前
|
数据采集 JSON 数据处理
抓取和分析JSON数据:使用Python构建数据处理管道
在大数据时代,电商网站如亚马逊、京东等成为数据采集的重要来源。本文介绍如何使用Python结合代理IP、多线程等技术,高效、隐秘地抓取并处理电商网站的JSON数据。通过爬虫代理服务,模拟真实用户行为,提升抓取效率和稳定性。示例代码展示了如何抓取亚马逊商品信息并进行解析。
抓取和分析JSON数据:使用Python构建数据处理管道
|
1月前
|
JSON 数据格式 索引
Python中序列化/反序列化JSON格式的数据
【11月更文挑战第4天】本文介绍了 Python 中使用 `json` 模块进行序列化和反序列化的操作。序列化是指将 Python 对象(如字典、列表)转换为 JSON 字符串,主要使用 `json.dumps` 方法。示例包括基本的字典和列表序列化,以及自定义类的序列化。反序列化则是将 JSON 字符串转换回 Python 对象,使用 `json.loads` 方法。文中还提供了具体的代码示例,展示了如何处理不同类型的 Python 对象。
|
1月前
|
JSON 缓存 前端开发
PHP如何高效地处理JSON数据:从编码到解码
在现代Web开发中,JSON已成为数据交换的标准格式。本文探讨了PHP如何高效处理JSON数据,包括编码和解码的过程。通过简化数据结构、使用优化选项、缓存机制及合理设置解码参数等方法,可以显著提升JSON处理的性能,确保系统快速稳定运行。
|
1月前
|
JSON API 数据安全/隐私保护
拍立淘按图搜索API接口返回数据的JSON格式示例
拍立淘按图搜索API接口允许用户通过上传图片来搜索相似的商品,该接口返回的通常是一个JSON格式的响应,其中包含了与上传图片相似的商品信息。以下是一个基于淘宝平台的拍立淘按图搜索API接口返回数据的JSON格式示例,同时提供对其关键字段的解释
|
2月前
|
JSON JavaScript Java
在Java中处理JSON数据:Jackson与Gson库比较
本文介绍了JSON数据交换格式及其在Java中的应用,重点探讨了两个强大的JSON处理库——Jackson和Gson。文章详细讲解了Jackson库的核心功能,包括数据绑定、流式API和树模型,并通过示例演示了如何使用Jackson进行JSON解析和生成。最后,作者分享了一些实用的代码片段和使用技巧,帮助读者更好地理解和应用这些工具。
156 0
在Java中处理JSON数据:Jackson与Gson库比较
|
2月前
|
JSON API 数据格式
商品详情数据JSON格式示例参考(api接口)
JSON数据格式的商品详情数据通常包含商品的多个层级信息,以下是一个综合多个来源信息的JSON数据格式的商品详情数据示例参考:
|
2月前
|
存储 JSON 前端开发
JSON与现代Web开发:数据交互的最佳选择
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也便于机器解析和生成。它以文本格式存储数据,常用于Web应用中的数据传输,尤其是在客户端和服务器之间。
78 0
|
2月前
|
存储 JavaScript 前端开发
TypeScript :使用mock提供数据&as const 的使用&tsconfig.json配置
本文介绍了如何在项目中使用 Mock 提供数据,包括安装依赖、配置 Vite 和 TypeScript,以及如何使用 `as const`、元组和 tsconfig.json 配置文件。通过这些配置,可以实现更灵活和高效的开发体验。
|
3月前
|
XML 存储 JSON
Twaver-HTML5基础学习(19)数据容器(2)_数据序列化_XML、Json
本文介绍了Twaver HTML5中的数据序列化,包括XML和JSON格式的序列化与反序列化方法。文章通过示例代码展示了如何将DataBox中的数据序列化为XML和JSON字符串,以及如何从这些字符串中反序列化数据,重建DataBox中的对象。此外,还提到了用户自定义属性的序列化注册方法。
49 1