IOS model的数据ios 属性和成员变量名重复 怎么处理

2822人阅读
JSONModel, Mantle
这两个开源库都是用来进行封装JSON-&Model的, 想想看, 直接向服务器发起一个请求,然后回来后,就是一个Model, 直接使用, 这是一个多么美好的事情。 感谢GitHub的开源精神。
那我们开始吧。&
先说说这两个的差别。
这两个使用的方法其实都差不多, 详细的使用方法请直接GitHub上找, 还是比较简单地。 就我个人来说JSONModel相对起来使用较为简单,而Mantle使用起来略为复杂,但是Mantle似乎比JSONModel更为强大。&
一般的项目,其实使用JSONModel就已经足够。&
&下面讲一下JSONModel的使用方法。&
@inteface MyModel : JSONModel
1. 使用JSONModel时,不需要额外去检查所要的服务器属性是否有返回。JSONModel的initWithDictionary方法会自动去进行检查并处理。
2. 有效性检查,如果指定的服务器返回的某个字段没有返回,而且又是必须的, 像下面这样写,则会抛出异常。
//this property is required
@property&(strong,&nonatomic) NSString*
因为默认这个值是必须的。
一般情况下,我们不想因为服务器的某个值没有返回就使程序崩溃, 我们会加关键字Optional.
//this one's optional
@property&(strong,&nonatomic) NSNumber&Optional&*
3. 原子数据, 之前可能是如下面这样操作数据
if&(jsonDict[@&name&])
labelName.text = jsonDict[@&name&];
[self&showErrorMessageAndBailout];
这段代码会使得jsonDict[@&name&], 会被读取,然后进行有效性判断,最后再被使用。 换句话来说,这里使用了三次, 而如果某些情况下,使用一次就已经出错,但却无法阻止它接下来的连续出错。
而如果使用JSONModel的属性,则只会保证上面只使用一次,就可以进行有效性的判断以及使用。(其实上面也可以做到,只需要把这个值取出来,存下来接着使用却可,但是代码会稍显麻烦)
同时读取一批数据如下面代码:
简单模型如下:
SimpleModel* model = [[SimpleModel alloc] initWithString:@&...json here...&&error:nil];
复杂模型如下, 这里假设复杂模型包含了简单模型。主要是为了说明模型之前的包含情况下,照样可以进行解析。
SuperComplicatedModel* model = [[SuperComplicatedModel alloc] initWithString:@&...json here...&&error:nil];
模型的批处理,即一次可以处理一批模型。
NSArray* models = [SuperComplicatedModel arrayOfObjectsFromDictionaries: jsonDatas error:nil];
4. 数据转换, OC &-& JSON
注意下面这张图:这意味着JSON的数据格式只有中间的部分, string,number, array, object, 以及null
例如有如下 JSON数据:
& &&first&&: 1,
& &&second&: 35,
& &&third&&: 10034,
& &&fourth&: 10000
可以如下定义这个模型
@interface&NumbersModel:JSONModel
@property&(assign,nonatomic)&short&
@property&(assign,nonatomic)&double&
@property&(strong,nonatomic)&NSNumber*
@property&(strong,nonatomic)&NSString*
注:JSON数据中, first为1,second为35, 但是它们却可以自动被转换成short, double类型。 对于10034, 以及10000会自动转换为NSNumber以及NSString。 这些都是JSONModel会自动进行的。 神奇吧!
5. 内嵌的数据转换, 在JSONValueTransformer类中,有各种内嵌的转换支持。如下面
& &&&purchaseDate&&:&&T10:00:01+02:00&,
& &&&blogURL&&:&&http://www.touch-&
分别是一个 日期类型,以及一个URL类型。
@interface&SmartModel:&JSONModel
@property&(strong,&nonatomic)&NSDate* purchaseD
@property&(strong,&nonatomic)&NSURL* blogU
用上面这个模型,不需要其它代码,即可以得到想要的转换 。
这个JSONValueTransformer类中有如下支持的转换
NSMutableString &-& NSString
NSMutableArray &-& NSArray
NS(Mutable)Array &- JSONModelArray
NSMutableDictionary &-& NSDictionary
NSSet &-& NSArray
BOOL &-& number/string
string &-& number
string &-& url
string &-& time zone
string &-& date
number &-& date
6. 自定义数据转换, 显然上面的内嵌转换有时不能满足我们的需要,所以我们需要如下的自定义转换。
你需要做的就是自定义一个JSONValueTransformer的类别文件,如下:
@interface&JSONValueTransformer(UIColor)
-(UIColor*)UIColorFromNSString:(NSString*)
-(id)JSONObjectFromUIColor:(UIColor*)
然后再进行实现即可。
注意上面的命名是采用:
-(YourPropertyClass*)YourPropertyClassFromJSONObjectClass:(JSONObjectClass*)
-(UIColor*)UIColorFromNSString:(NSString*)
而要把这个类型转换为JSON,则像这样即可:(注下面这个id,可以修改也可以不用修改成NSString,因为一定知道这是一个nsstirng. &heqin:这里其实也可能会是其它类的,应该是根据特定情况来特定判断。)
-(id)JSONObjectFromYourPropertyClass:(YourPropertyClass*)
如下是另一个例子:
@implementation&JSONValueTransformer (CustomTransformer)
- (NSDate&*)NSDateFromNSString:(NSString*)string {
& &&NSDateFormatter&*formatter = [[NSDateFormatter&alloc]&init];
& & [formatter setDateFormat:APIDateFormat];
& &&return&[formatter&dateFromString:string];
- (NSString&*)JSONObjectFromNSDate:(NSDate&*)date {
& &&NSDateFormatter&*formatter = [[NSDateFormatter&alloc]&init];
& & [formatter setDateFormat:APIDateFormat];
& &&return&[formatter&stringFromDate:date];
7. 层级嵌套。
& &&&idImage&: 1,
& &&&name&:&&house.jpg&,
& &&&copyright&: {&author&:&Marin Todorov&,&&year&:2012}
可以先定义如下的模型
@interface&CopyModel:&JSONModel
@property&(strong,&nonatomic)&NSString*
@property&(assign,&nonatomic)&int&
然后再定义模型:
#import&&CopyModel.h&
@interface&ImageModel:&JSONModel
@property&(assign,&nonatomic)&int&idI
@property&(strong,&nonatomic)&NSString*
@property&(strong,&nonatomic) CopyModel*
然后在你得到的ImageModel后, 就会发现其中的CopyModel也有数据了。&
如果你想要一个数组的模型属性,如下即可。
@property&(strong,&nonatomic) NSArray&TweetModel&*
8. JSONModel转换为Dictioanry, JSONString.&
直接使用JSONModel的方法toDictioanry, 以及toJSONString即可。
9. 保存model数据
NSDictionary* object = [NSDictionary dictionaryWithContentsOfFile:filePath];
data = [[MyDataModel alloc] initWithDictionary: object];
//保存操作
[[data toDictionary] writeToFile:filePath atomically:YES];
10. Key mapping, 有时, 得到的数据不是在一个层级,如下:
& &&&order_id&: 104,
& &&&order_details&&: [
&& & & & & & & & & & & {
&& & & & & & & & & & & & &&&name&:&&Product#1&,
&& & & & & & & & & & & & &&&price&: {
&& & & & & & & & & & & & & & &&&usd&: 12.95
&& & & & & & & & & & & & & }
&& & & & & & & & & & & }
&& & & & & & & & & & & ]
其中的order_id与name就不是一个层级,但我们仍然想在一个model中得到它们的数据。 如下:
@interface&OrderModel :&JSONModel
@property&(assign,&nonatomic)&int&id;
@property&(assign,&nonatomic)&float&
@property&(strong,&nonatomic)&NSString* productN
@implementation&OrderModel
+(JSONKeyMapper*)keyMapper
& &&return&[[JSONKeyMapper&alloc]&initWithDictionary:@{
&& & & & & & & & & & & & & & & & & & & & & & & & & & &&@&order_id&:&@&id&,
&& & & & & & & & & & & & & & & & & & & & & & & & & & &&@&order_details.name&:&@&productName&,
&& & & & & & & & & & & & & & & & & & & & & & & & & & &&@&order_details.price.usd&:&@&price&
//&这里就采用了KVC的方式来取值,它赋给price属性
&& & & & & & & & & & & & & & & & & & & & & & & & & & & }];
11. 全局Global key mapping. (使所有的模型都具备), 个人觉得这个并不是非常通用,因为如果真是需要所有模型都具备这个keyMapper的转换,则直接继承一个基类就行了。
[JSONModel setGlobalKeyMapper:[
&& & & & & & & & & & & & & & & [JSONKeyMapper alloc] initWithDictionary:@{
& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & &@&item_id&:@&ID&,
& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & &&@&item.name&:&@&itemName&
& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & }]
12. 自动把下划线方式的命名转为驼峰命名属性。还有类似的,如大写转为小写的方法:mapperFromUpperCaseToLowerCase
& &&&order_id&: 104,
& &&&order_product&&:&@&Product#1&,
& &&&order_price&&: 12.95
生成的模型
@interface&OrderModel :&JSONModel
@property&(assign,&nonatomic)&int&orderId;
@property&(assign,&nonatomic)&float&orderP
@property&(strong,&nonatomic)&NSString* orderP
@implementation&OrderModel
+(JSONKeyMapper*)keyMapper
& &&return&[JSONKeyMapper&mapperFromUnderscoreCaseToCamelCase];
13. 可选属性,建议尽量使用这种方式来避免异常。
& &&&id&:&&123&,
& &&&name&: null,
& &&&price&: 12.95
生成的模型如下:
@interface&ProductModel :&JSONModel
@property&(assign,&nonatomic)&int&id;
@property&(strong,&nonatomic)&NSString&Optional&*
@property&(assign,&nonatomic)&float&
@property&(strong,&nonatomic)&NSNumber&Optional&*
@implementation&ProductModel
通过上面的optional的方式, 我们可以给这个类添加一个isSuccess方法,该方法中判断name和uuid是否存在来决定是否从服务器成功取数据。 而不是把这两个属性设置为required,可以有效避免异常。
14. Ignore属性, 会使得解析时会完全忽略它。 一般情况下,忽略的属性主要用在该值不从服务器获取,而是通过后面的代码进行设置。
& &&&id&:&&123&,
& &&&name&: null
@interface&ProductModel :&JSONModel
@property&(assign,&nonatomic)&int&id;
@property&(strong,&nonatomic)&NSString&Ignore&*
@implementation&ProductModel
可以用下面方法,使当前类的全部属性都为可选,官网上说尽量避免这样的使用, (个人觉得官网的意思是指,尽量避免用来面方法来指定所有的属性为可选,即使要全部属性为可选,也尽量是在每个属性那里标注为Optional)
@implementation&ProductModel
+(BOOL)propertyIsOptional:(NSString*)propertyName
& &&return&YES;
15. 延迟加载, 这种比较推荐,可以减少在网络读取时的性能消耗:关键字为: ConvertOnDemand
& &&&order_id&: 104,
& &&&total_price&: 103.45,
& &&&products&&: [
& & & & & & & & & {
& & & & & & & & & & &&&id&:&&123&,
& & & & & & & & & & &&&name&:&&Product #1&,
& & & & & & & & & & &&&price&: 12.95
& & & & & & & & & },
& & & & & & & & & {
& & & & & & & & & & &&&id&:&&137&,
& & & & & & & & & & &&&name&:&&Product #2&,
& & & & & & & & & & &&&price&: 82.95
& & & & & & & & & }
& & & & & & & & & ]
使用模型:
@protocol&ProductModel
@interface&ProductModel :&JSONModel
@property&(assign,&nonatomic)&int&id;
@property&(strong,&nonatomic)&NSString*
@property&(assign,&nonatomic)&float&
@implementation&ProductModel
@interface&OrderModel :&JSONModel
@property&(assign,&nonatomic)&int&order_
@property&(assign,&nonatomic)&float&total_
@property&(strong,&nonatomic)&NSArray&ProductModel,&ConvertOnDemand&*
@implementation&OrderModel
16. 使用JSONHttpClient进行请求。&
//add extra headers
[[JSONHTTPClient requestHeaders] setValue:@&MySecret&&forKey:@&AuthorizationToken&];
//make post, get requests
[JSONHTTPClient postJSONFromURLWithString:@&/api&
&& & & & & & & & & & & & & & & & & params:@{@&postParam1&:@&value1&}
&& & & & & & & & & & & & & & & completion:^(id&json, JSONModelError *err) {
& & & & & & & & & & & & & & & & & &
&& & & & & & & & & & & & & & & & &&//check err, process json ...
& & & & & & & & & & & & & & & & & &
&& & & & & & & & & & & & & & & }];
好了, 所以的JSONModel的使用方法都已经在这里了, 综合了官网的使用方法。&
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:186083次
积分:2230
积分:2230
排名:第12214名
转载:135篇
评论:22条
(25)(15)(2)(3)(3)(18)(6)(9)(2)(3)(2)(19)(1)(1)(13)(4)(1)(7)(3)(1)(3)(1)(2)iOS中JSONModel的使用 - 简书
下载简书移动应用
写了2876字,被43人关注,获得了13个喜欢
iOS中JSONModel的使用
流弊的JSON数据模型框架
版本 1.3.0
如果你喜欢JSONModel,并且使用了它,请你:
给我一些反馈. 多谢!
JSONModel for iOS and OSX
JSONModel 是一个能够快速巧妙的创建数据模型的库. 你可以在 iOS or OSX APP中使用它.
JSONModel 自动检查JOSN模型和结构体, 彻底的减少你的代码量.
添加JSONModel到你的项目中
支持持ARC; iOS 5.0+ / OSX 10.7+
SystemConfiguration.framework
as: 1) 源文件
1.下载JSONModel.zip文件2.将它拷贝到你的项目中3.导入SystemConfiguration.framework框架
or 2)使用 CocoaPods
pod 'JSONModel'
如果你想关于CocoaPods了解更多,请参考这个简单的.
or 3) 使用 Carthage
在你的项目的Cartfile添加JSONModel:
github "jsonmodel/jsonmodel"
你可以查看在线阅读文档:
涉想你的JSON数据像这样:
{ "id": "10", "country": "Germany", "dialCode": 49, "isInEurope": true }
为你的数据模型创建一个Objective-C的类,继承自JSONModel.
将JSON中的keys在.h文件中声明为属性:
#import "JSONModel.h"
@interface CountryModel : JSONModel
@property (assign, nonatomic)
@property (strong, nonatomic) NSString*
@property (strong, nonatomic) NSString* dialC
@property (assign, nonatomic) BOOL isInE
在.m文件中不需要做任何事情.
用数据初始化你的model:
#import "CountryModel.h"
NSString* json = (fetch here JSON from Internet) ...
NSError* err =
CountryModel* country = [[CountryModel alloc] initWithString:json error:&err];
如果传过来的JSON合法,你所定义的所有的属性都会与该JSON的值想对应,甚至JSONModel会尝试去转换数据为你期望的类型,如上所示:
转换id,从字符串转换为int
只需要拷贝一下country的值
转换diaCode,从number转换为字符串
最后一个是将isInEurope转换为BOOL属性
所以,你所需要做的就是将你的属性定义为期望的类型.
命名自动匹配
"id": "123",
"name": "Product name",
"price": 12.95
@interface ProductModel : JSONModel
@property (assign, nonatomic)
@property (strong, nonatomic) NSString*
@property (assign, nonatomic)
@implementation ProductModel
模型嵌套 (模型包含其他模型)
"order_id": 104,
"total_price": 13.45,
"product" : {
"id": "123",
"name": "Product name",
"price": 12.95
@interface OrderModel : JSONModel
@property (assign, nonatomic) int order_
@property (assign, nonatomic) float total_
@property (strong, nonatomic) ProductModel*
@implementation OrderModel
"order_id": 104,
"total_price": 103.45,
"products" : [
"id": "123",
"name": "Product #1",
"price": 12.95
"id": "137",
"name": "Product #2",
"price": 82.95
@protocol ProductModel
@interface ProductModel : JSONModel
@property (assign, nonatomic)
@property (strong, nonatomic) NSString*
@property (assign, nonatomic)
@implementation ProductModel
@interface OrderModel : JSONModel
@property (assign, nonatomic) int order_
@property (assign, nonatomic) float total_
@property (strong, nonatomic) NSArray&ProductModel&*
@implementation OrderModel
注意: 尖括号后 NSArray 包含一个协议. 这跟Objective-C原生的泛型不是一个概念. 他们不会冲突, 但对于JSONModel来说,协议必须在一个地方声明.
"order_id": 104,
"order_details" : [
"name": "Product#1",
"price": {
"usd": 12.95
@interface OrderModel : JSONModel
@property (assign, nonatomic)
@property (assign, nonatomic)
@property (strong, nonatomic) NSString* productN
@implementation OrderModel
+(JSONKeyMapper*)keyMapper
return [[JSONKeyMapper alloc] initWithDictionary:@{
@"order_id": @"id",
@"order_details.name": @"productName",
@"order_details.price.usd": @"price"
设置全局键映射(应用于所有model)
[JSONModel setGlobalKeyMapper:[
[JSONKeyMapper alloc] initWithDictionary:@{
@"item_id":@"ID",
@"item.name": @"itemName"
设置下划线自动转驼峰
"order_id": 104,
"order_product" : @"Product#1",
"order_price" : 12.95
@interface OrderModel : JSONModel
@property (assign, nonatomic) int orderId;
@property (assign, nonatomic) float orderP
@property (strong, nonatomic) NSString* orderP
@implementation OrderModel
+(JSONKeyMapper*)keyMapper
return [JSONKeyMapper mapperFromUnderscoreCaseToCamelCase];
可选属性 (就是说这个属性可以为null或者为空)
"id": "123",
"name": null,
"price": 12.95
@interface ProductModel : JSONModel
@property (assign, nonatomic)
@property (strong, nonatomic) NSString&Optional&*
@property (assign, nonatomic)
@property (strong, nonatomic) NSNumber&Optional&*
@implementation ProductModel
忽略属性 (就是完全忽略这个属性)
"id": "123",
"name": null
@interface ProductModel : JSONModel
@property (assign, nonatomic)
@property (strong, nonatomic) NSString&Ignore&* customP
@implementation ProductModel
设置所有的属性为可选(所有属性值可以为空)
@implementation ProductModel
+(BOOL)propertyIsOptional:(NSString*)propertyName
return YES;
使用JSONModel自带的 HTTP 请求
//add extra headers
[[JSONHTTPClient requestHeaders] setValue:@"MySecret" forKey:@"AuthorizationToken"];
//make post, get requests
[JSONHTTPClient postJSONFromURLWithString:@"/api"
params:@{@"postParam1":@"value1"}
completion:^(id json, JSONModelError *err) {
//check err, process json ...
将model转化为字典或者json格式的字符串
ProductModel* pm = [[ProductModel alloc] initWithString:jsonString error:nil];
pm.name = @"Changed Name";
//convert to dictionary
NSDictionary* dict = [pm toDictionary];
//convert to text
NSString* string = [pm toJSONString];
自定义数据的转换
@implementation JSONValueTransformer (CustomTransformer)
- (NSDate *)NSDateFromNSString:(NSString*)string {
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:APIDateFormat];
return [formatter dateFromString:string];
- (NSString *)JSONObjectFromNSDate:(NSDate *)date {
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:APIDateFormat];
return [formatter stringFromDate:date];
自定义处理指定的属性
@interface ProductModel : JSONModel
@property (assign, nonatomic)
@property (strong, nonatomic) NSString*
@property (assign, nonatomic)
@property (strong, nonatomic) NSLocale *
@implementation ProductModel
// Convert and assign the locale property
- (void)setLocaleWithNSString:(NSString*)string {
self.locale = [NSLocale localeWithLocaleIdentifier:string];
- (NSString *)JSONObjectForLocale {
return self.locale.localeI
自定义JSON校验
@interface ProductModel : JSONModel
@property (assign, nonatomic)
@property (strong, nonatomic) NSString*
@property (assign, nonatomic)
@property (strong, nonatomic) NSLocale *
@property (strong, nonatomic) NSNumber &Ignore& *minNameL
@implementation ProductModel
- (BOOL)validate:(NSError *__autoreleasing *)error {
BOOL valid = [super validate:error];
if (self.name.length & self.minNameLength.integerValue) {
*error = [NSError errorWithDomain:@"" code:1 userInfo:nil];
valid = NO;
自定义数据校验
自动比较和相等判断
参与者: Christian Hoffmann, Mark Joslin, Julien Vignali, Symvaro GmbH, BB9z.任何人都可以 .
Utility to generate JSONModel classes from JSON data:
This code is distributed under the terms and conditions of the MIT license.
NB! 如果你解决了你发现的某个BUG, 请添加单元测试,这样以便我在合并之前复现这个BUG.
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
被以下专题收入,发现更多相似内容:
· 6163人关注
心情不好的时候问自己 :
我为何这么屌
心情好的时候问自己 : 为什么比我屌的这么多
· 3551人关注
关于iOS开发的一些代码,工具,技巧等
· 1163人关注
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
选择支付方式:下次自动登录
现在的位置:
& 综合 & 正文
ios开发点滴-model属性不能用new开头的问题
由于现在ios版本需要用到以前android项目的那套服务,那么,android那边的model也得照搬过来,但是在移植的过程中发现个问题,比如说一个属性的名字为newPasswd,在ios这边,如果使用了ARC,model 的字段(属性)名称还叫newPasswd的话,编译就会不通过,出现以下错误:
error: property's synthesized getter follows Cocoa naming convention for returning 'owned' objects
/Users/senyang/Documents/work/project/../xxxx.h:15:38: note: property declared here
@property (nonatomic,copy) NSString *newP
出现这个错误有两种解决办法:
1.改掉newPasswd这个属性的名称,变成其他的只要不是new开头的就行,错误消除,但是这样在进行json自动转化的时候会出错,所以这种方式我不能使用(也许有其他的什么映射的方法解决这个问题,为了时间关系,我这里暂时不做深究);
2.在@property声明属性的时候重新定义它的Getter方法:
@property (nonatomic,copy,getter = theNewPasswd) NSString *newP
编译通过,只不过使用Getter方法的时候注意下
最后附上stackoverflow的问题解决传送门
&&&&推荐文章:
【上篇】【下篇】<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
您的访问请求被拒绝 403 Forbidden - ITeye技术社区
您的访问请求被拒绝
亲爱的会员,您的IP地址所在网段被ITeye拒绝服务,这可能是以下两种情况导致:
一、您所在的网段内有网络爬虫大量抓取ITeye网页,为保证其他人流畅的访问ITeye,该网段被ITeye拒绝
二、您通过某个代理服务器访问ITeye网站,该代理服务器被网络爬虫利用,大量抓取ITeye网页
请您点击按钮解除封锁&}

我要回帖

更多关于 ios 属性和成员变量 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信