多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > 綜合技術 > 用 KVC 自動把 JSON 轉 Model

用 KVC 自動把 JSON 轉 Model

來源:程序員人生   發布時間:2015-03-27 08:31:56 閱讀次數:4186次


圖1和圖2是1個接口,code 是在服務器修改或升級等緣由致使的;圖3是在新用戶登錄沒有數據的情況出現的;是1個接口對應的Model類也是1個;Model類代碼以下

@interface SHYProduct : NSObject @property (nonatomic, assign) int code; @property (nonatomic, strong) NSString *msg; @property (nonatomic, strong) NSArray *data; @end @interface SHYProductItem : NSObject @property (nonatomic, strong) NSString *title; @end #import "SHYProduct.h" @implementation SHYProduct - (void)dealloc { _msg = nil; _data = nil; } @end @implementation SHYProductItem - (void)dealloc { _title = nil; } @end

之前我們在轉Model是這樣寫的

NSString *json = @"{"code":"200","msg":"u83b7u53d6u6210u529f","data":[{"title":"title 3"},{"title":"title 4"}]}"; NSData *jsonData = [json dataUsingEncoding:NSUTF8StringEncoding]; NSDictionary *body = kNSDictionary([NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:nil]); SHYProduct *product = [[SHYProduct alloc] init]; product.code = [body intForKey:@"code"]; product.msg = [body stringForKey:@"msg"]; NSArray *rows = [body arrayForKey:@"data"]; NSMutableArray *items = [[NSMutableArray alloc] init]; for (id row in rows) { NSDictionary *dictionary = kNSDictionary(row); SHYProductItem *item = [[SHYProductItem alloc] init]; item.title = [dictionary stringForKey:@"title"]; [items addObject:item]; } product.data = items;

這樣寫沒有甚么錯,唯1的是代碼大,體力活;

關于 intForKey 之類的方法請看 網絡接口協議 JSON 解析 Crash 的哪些事

如果我們不想做這個體力活;有無辦法呢;辦法是有1個的,用KVC + Runtime;在用這個之前我們要確認1點用KVC code字段有數字和字符串能不能轉成int類型;是不是可以測試1下就知道;代碼以下:

NSString *json = @"{"code":"200","msg":"u83b7u53d6u6210u529f","data":[{"title":"title 3"},{"title":"title 4"}]}"; NSData *jsonData = [json dataUsingEncoding:NSUTF8StringEncoding]; NSDictionary *body = kNSDictionary([NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:nil]); SHYProduct *product = [[SHYProduct alloc] init]; [product setValue:[body valueForKey:@"code"] forKey:@"code"];//這里會轉成數字,KVC自動轉換了 [product setValue:[body valueForKey:@"msg"] forKey:@"msg"]; NSArray *rows = [body arrayForKey:@"data"]; NSMutableArray *items = [[NSMutableArray alloc] init]; for (id row in rows) { NSDictionary *dictionary = kNSDictionary(row); SHYProductItem *item = [[SHYProductItem alloc] init]; [item setValue:[dictionary valueForKey:@"title"] forKey:@"title"]; [items addObject:item]; } product.data = items;

運行1下code值過去了;JSON的code是數字和字符串最后都能變成int類型;這下好辦了寫1個Model基類就能夠替換體力活了;代碼以下:(開源代碼https://github.com/elado/jastor)

#import <Foundation/Foundation.h> /*! @class SHYJastor @abstract 把 NSDictionary 轉成 model 用的 */ @interface SHYJastor : NSObject<NSCoding> /*! @property objectId @abstract 對象的id */ @property (nonatomic, copy) NSString *objectId; /*! @method objectWithDictionary: @abstract 指定 NSDictionary 對象轉成 model 對象 @param dictionary NSDictionary的對象 @result 返回 model 對象 */ + (id)objectWithDictionary:(NSDictionary *)dictionary; /*! @method initWithDictionary: @abstract 指定 NSDictionary 對象轉成 model 對象 @param dictionary NSDictionary的對象 @result 返回 model 對象 */ - (id)initWithDictionary:(NSDictionary *)dictionary; /*! @method dictionaryValue @abstract 把對象轉成 NSDictionary 對象 @result 返回 NSDictionary 對象 */ - (NSMutableDictionary *)dictionaryValue; /*! @method mapping @abstract model 屬性 與 NSDictionary 不1至時的映照 */ - (NSDictionary *)mapping; @end #import "SHYJastor.h" #import "SHYJastorRuntimeHelper.h" #import "NSArray+SHYUtil.h" #import "NSDictionary+SHYUtil.h" static NSString *idPropertyName = @"id"; static NSString *idPropertyNameOnObject = @"objectId"; @implementation SHYJastor Class dictionaryClass; Class arrayClass; + (id)objectWithDictionary:(NSDictionary *)dictionary { id item = [[self alloc] initWithDictionary:dictionary]; return item; } - (id)initWithDictionary:(NSDictionary *)dictionary { if (!dictionaryClass) dictionaryClass = [NSDictionary class]; if (!arrayClass) arrayClass = [NSArray class]; self = [super init]; if (self) { NSDictionary *maps = [self mapping]; NSArray *propertys = [SHYJastorRuntimeHelper propertyNames:[self class]]; for (NSDictionary *property in propertys) { NSString *propertyName = [property stringForKey:@"name"]; id key = [maps valueForKey:propertyName]; id value = [dictionary valueForKey:key]; if (value == [NSNull null] || value == nil) { continue; } if ([SHYJastorRuntimeHelper isPropertyReadOnly:[property stringForKey:@"attributes"]]) { continue; } if ([value isKindOfClass:dictionaryClass]) { Class aClass = NSClassFromString([property stringForKey:@"type"]); if (![aClass isSubclassOfClass:[NSDictionary class]]) { continue; } value = [[aClass alloc] initWithDictionary:value]; } else if ([value isKindOfClass:arrayClass]) { NSArray *items = (NSArray *)value; NSMutableArray *objects = [NSMutableArray arrayWithCapacity:[items count]]; for (id item in items) { if ([[item class] isSubclassOfClass:dictionaryClass]) { SEL selector = NSSelectorFromString([NSString stringWithFormat:@"%@Class", propertyName]); #pragma clang diagnostic push #pragma clang diagnostic ignored "-Warc-performSelector-leaks" Class aClass = ([[self class] respondsToSelector:selector]) ? [[self class] performSelector:selector] : nil; #pragma clang diagnostic pop if ([aClass isSubclassOfClass:[NSDictionary class]]) { [objects addObject:item]; } else if ([aClass isSubclassOfClass:[SHYJastor class]]) { SHYJastor *childDTO = [[aClass alloc] initWithDictionary:item]; [objects addObject:childDTO]; } } else { [objects addObject:item]; } } value = objects; } [self setValue:value forKey:propertyName]; } id objectId; if ((objectId = [dictionary objectForKey:idPropertyName]) && objectId != [NSNull null]) { if (![objectId isKindOfClass:[NSString class]]) { objectId = [NSString stringWithFormat:@"%@", objectId]; } [self setValue:objectId forKey:idPropertyNameOnObject]; } } return self; } - (void)dealloc { _objectId = nil; } - (void)encodeWithCoder:(NSCoder *)encoder { [encoder encodeObject:_objectId forKey:idPropertyNameOnObject]; NSArray *propertys = [SHYJastorRuntimeHelper propertyNames:[self class]]; for (NSDictionary *property in propertys) { NSString *propertyName = [property stringForKey:@"name"]; [encoder encodeObject:[self valueForKey:propertyName] forKey:propertyName]; } } - (id)initWithCoder:(NSCoder *)decoder { self = [super init]; if (self) { [self setValue:[decoder decodeObjectForKey:idPropertyNameOnObject] forKey:idPropertyNameOnObject]; NSArray *propertys = [SHYJastorRuntimeHelper propertyNames:[self class]]; for (NSDictionary *property in propertys) { NSString *propertyName = [property stringForKey:@"name"]; if ([SHYJastorRuntimeHelper isPropertyReadOnly:[property stringForKey:@"attributes"]]) { continue; } id value = [decoder decodeObjectForKey:propertyName]; if (value != [NSNull null] && value != nil) { [self setValue:value forKey:propertyName]; } } } return self; } - (NSMutableDictionary *)dictionaryValue { NSMutableDictionary *infos = [NSMutableDictionary dictionary]; if (_objectId) { [infos setObject:_objectId forKey:idPropertyName]; } NSDictionary *maps = [self mapping]; NSArray *propertys = [SHYJastorRuntimeHelper propertyNames:[self class]]; for (NSDictionary *property in propertys) { NSString *propertyName = [property stringForKey:@"name"]; id value = [self valueForKey:propertyName]; if (value && [value isKindOfClass:[SHYJastor class]]) { [infos setObject:[value dictionary] forKey:[maps valueForKey:propertyName]]; } else if (value && [value isKindOfClass:[NSArray class]] && ((NSArray *)value).count > 0) { id internalValue = [value objectForKeyCheck:0]; if (internalValue && [internalValue isKindOfClass:[SHYJastor class]]) { NSMutableArray *internalItems = [NSMutableArray array]; for (id item in value) { [internalItems addObject:[item dictionary]]; } [infos setObject:internalItems forKey:[maps valueForKey:propertyName]]; } else { [infos setObject:value forKey:[maps valueForKey:propertyName]]; } } else if (value != nil) { [infos setObject:value forKey:[maps valueForKey:propertyName]]; } } return infos; } - (NSDictionary *)mapping { NSArray *properties = [SHYJastorRuntimeHelper propertyNames:[self class]]; NSMutableDictionary *maps = [[NSMutableDictionary alloc] initWithCapacity:properties.count]; for (NSDictionary *property in properties) { NSString *propertyName = [property stringForKey:@"name"]; [maps setObject:propertyName forKey:propertyName]; } return maps; } - (NSString *)description { NSMutableDictionary *dictionary = [self dictionaryValue]; return [NSString stringWithFormat:@"#<%@: id = %@ %@>", [self class], _objectId, [dictionary description]]; } - (BOOL)isEqual:(id)object { if (object == nil || ![object isKindOfClass:[SHYJastor class]]) { return NO; } SHYJastor *model = (SHYJastor *)object; return [_objectId isEqualToString:model.objectId]; } @end @interface SHYJastorRuntimeHelper : NSObject + (BOOL)isPropertyReadOnly:(NSString *)attributes; + (NSArray *)propertyNames:(__unsafe_unretained Class)aClass; @end #import <objc/runtime.h> #import "SHYJastor.h" #import "SHYJastorRuntimeHelper.h" #import "NSArray+SHYUtil.h" #import "NSDictionary+SHYUtil.h" #include <string.h> static NSMutableDictionary *propertyListByClass; static const char *property_getTypeName(const char *attributes) { char buffer[strlen(attributes) + 1]; strncpy(buffer, attributes, sizeof(buffer)); char *state = buffer, *attribute; while ((attribute = strsep(&state, ",")) != NULL) { if (attribute[0] == 'T') { size_t len = strlen(attribute); attribute[len - 1] = ' 主站蜘蛛池模板: 欧美一级一毛片 | 欧美a在线 | 视频在线高清完整免费观看 | 欧美一级片免费观看 | 成人亚洲国产精品久久 | 手机看片日韩高清国产欧美 | 亚洲国产人久久久成人精品网站 | 好大好湿好硬顶到了好爽在 | 精品国产一区二区三区久久影院 | 99精品国产美女福到在线不卡 | 日韩欧美一区二区中文字幕 | 国产成人高清精品免费5388密 | 亚洲精品国产77777 | 日本一区二区三 | 久久精品一品道久久精品9 久久精品一区二区 | 男女xx00 | 狠狠躁天天躁夜夜躁夜天战 | 亚洲五月婷婷 | 国产又黄又爽又色的免费 | 国产视频二区在线观看 | 国产一区视频在线播放 | 日韩人成 | 亚洲永久精品一区二区三区 | 亚洲精品人成在线观看 | 99热色| 亚洲精品福利在线观看 | 亚洲国产一区视频 | 一区二区三区网站 | 日本欧美一区二区三区 | 精彩视频一区二区三区 | 国产精品第1页在线播放 | 一区二区三区在线播放 | 日韩在线 | 中文 | 亚洲精品日本 | 国内交换一区二区三区 | 亚洲人成图片欧美人成图片 | 网友自拍区一区二区三区 | 国产一区亚洲欧美成人 | 国产亚洲福利精品一区二区 | free 英国性xxxxhd | 性欧美黑人 |