第十四章 REST解惑——初识KVC
来源:互联网 发布:123d软件下载 编辑:程序博客网 时间:2024/05/20 18:49
一.KVC的基本概念
Key-value coding,它是一种使用字符串标识符,间接访问对象属性的机制,而不是直接调用getter 和 setter方法。通常我们使用valueForKey 来替代getter 方法,setValue:forKey来代替setter方法。
下面,给大家一个例子,基础流程是这样的:
首先,创建基类,主要方法:
//根据这个来把key-value 自动分配到对应的属性- (id) initWithDictionary:(NSMutableDictionary *) jsonObject;
然后,创建model类,继承自基类
model类需要实现方法
//如果遇到字典的key与model类中的属性名称不对应的情况,需要自己处理- (void)setValue:(id)value forUndefinedKey:(NSString *)key//一般的赋值,key与model类中的属性名相同,处理一些特殊逻辑- (void)setValue:(id)value forKey:(NSString *)key
各位还是通过代码来看下吧:
基类:JSONModel.h
//// JSONModel.h// iHotelApp_Demo//// Created by Eric on 14-1-13.// Copyright (c) 2014年 Eric. All rights reserved.//#import <Foundation/Foundation.h>@interface JSONModel : NSObject<NSCopying,NSCoding,NSMutableCopying>{}- (id) initWithDictionary:(NSMutableDictionary *) jsonObject;@end
JSONModel.m
//// JSONModel.m// iHotelApp_Demo//// Created by Eric on 14-1-13.// Copyright (c) 2014年 Eric. All rights reserved.//#import "JSONModel.h"@implementation JSONModel//根据字典初始化- (id)initWithDictionary:(NSMutableDictionary *)jsonObject{ self = [super init]; if (self) { [self setValuesForKeysWithDictionary:jsonObject]; } return self;}//允许编码- (BOOL) allowsKeyedCoding{ return YES;}- (id) initWithCoder:(NSCoder *)aDecoder{ return self;}- (void)encodeWithCoder:(NSCoder *)aCoder{ //do nothing}//复制一个副本- (id)mutableCopyWithZone:(NSZone *)zone{ JSONModel *newModel = [[JSONModel allocWithZone:zone] init]; return newModel;}//复制一个副本- (id)copyWithZone:(NSZone *)zone{ JSONModel *newModel = [[[self class] allocWithZone:zone] init]; return newModel;}//找未找到的Key- (id) valueForUndefinedKey:(NSString *)key{ NSLog(@"Undefined Key: %@",key); return nil;}//设置未找到的Key- (void)setValue:(id)value forUndefinedKey:(NSString *)key{ NSLog(@"Undefined Key: %@",key);}@end
实体类:MenuItem.h JSONModel的子类。
//// MenuItem.h// iHotelApp_Demo//// Created by Eric on 14-1-14.// Copyright (c) 2014年 Eric. All rights reserved.//#import "JSONModel.h"#import <Foundation/Foundation.h>/* "id": "JAP122", "image": "http://d1.myhotel.com/food_image1.jpg", "name": "Teriyaki Bento", "spicyLevel": 2, "rating" : 4, "description" : "Teriyaki Bento is one of the best lorem ipsum dolor sit", "waitingTime" : "930", "reviewCount" : 4 */@interface MenuItem : JSONModel@property (nonatomic,strong) NSString *itemId;@property (nonatomic,strong) NSString *image;@property (nonatomic,strong) NSString *name;@property (nonatomic,strong) NSString *spicyLevel;@property (nonatomic,strong) NSString *rating;@property (nonatomic,strong) NSString *itemDescription;@property (nonatomic,strong) NSString *waitingTime;@property (nonatomic,strong) NSString *reviewCount;@property (nonatomic,strong) NSMutableArray *reviews;@end
MenuItem.m
MenuItem 自定义实现解码,编码的方法,这样,基类JSONModel中的
initWithDictionary方法,便可以实现key-value与类属性的相对应
//// MenuItem.m// iHotelApp_Demo//// Created by Eric on 14-1-14.// Copyright (c) 2014年 Eric. All rights reserved.//#import "MenuItem.h"#import "Review.h"@implementation MenuItem- (id)init{ self = [super init]; if (self) { self.reviews = [NSMutableArray array]; } return self;}//在赋值的过程中,如果发现未声明的Key- (void)setValue:(id)value forUndefinedKey:(NSString *)key{ if ([key isEqualToString:@"id"]) { self.itemId = value; } else if([key isEqualToString:@"description"]){ self.itemDescription = value; }else{ [super setValue:value forUndefinedKey:key]; }}//赋值- (void)setValue:(id)value forKey:(NSString *)key{ if ([key isEqualToString:@"reviews"]) { for (NSMutableDictionary *reviewArrayDic in value) { Review *thisReview = [[Review alloc] initWithDictionary:reviewArrayDic]; [self.reviews addObject:thisReview]; } }else{ [super setValue:value forKey:key]; }}- (void)encodeWithCoder:(NSCoder *)aCoder{ [aCoder encodeObject:self.itemId forKey:@"itemId"]; [aCoder encodeObject:self.image forKey:@"image"]; [aCoder encodeObject:self.name forKey:@"name"]; [aCoder encodeObject:self.spicyLevel forKey:@"spicyLevel"]; [aCoder encodeObject:self.rating forKey:@"rating"]; [aCoder encodeObject:self.itemDescription forKey:@"itemDescription"]; [aCoder encodeObject:self.waitingTime forKey:@"waitingTime"]; [aCoder encodeObject:self.reviewCount forKey:@"reviewCount"]; [aCoder encodeObject:self.reviews forKey:@"reviews"];}- (id)initWithCoder:(NSCoder *)decoder{ self = [super init]; if (self) { self.itemId = [decoder decodeObjectForKey:@"itemId"]; self.image = [decoder decodeObjectForKey:@"image"]; self.name = [decoder decodeObjectForKey:@"name"]; self.spicyLevel = [decoder decodeObjectForKey:@"spicyLevel"]; self.rating = [decoder decodeObjectForKey:@"rating"]; self.itemDescription = [decoder decodeObjectForKey:@"itemDescription"]; self.waitingTime = [decoder decodeObjectForKey:@"waitingTime"]; self.reviewCount = [decoder decodeObjectForKey:@"reviewCount"]; self.reviews = [decoder decodeObjectForKey:@"reviews"]; } return self;}- (id)copyWithZone:(NSZone *)zone{ id theCopy = [[[self class] allocWithZone:zone] init]; // use designated initializer [theCopy setItemId:[self.itemId copy]]; [theCopy setImage:[self.image copy]]; [theCopy setName:[self.name copy]]; [theCopy setSpicyLevel:[self.spicyLevel copy]]; [theCopy setRating:[self.rating copy]]; [theCopy setItemDescription:[self.itemDescription copy]]; [theCopy setWaitingTime:[self.waitingTime copy]]; [theCopy setReviewCount:[self.reviewCount copy]]; [theCopy setReviews:[self.reviews copy]]; return theCopy;}@end
具体使用:
RESTfulEngine.m
//根据dict得到MenuItem实例[[MenuItem alloc] initWithDictionary:obj]
- (RESTfulOperation *)fetchMenuItemsOnSucceeded:(ArrayBlock)succeedBlock onError:(ErrorBlock)errorBlock{ RESTfulOperation *op = (RESTfulOperation *)[self operationWithPath:MENU_ITEMS_URL]; [op onCompletion:^(MKNetworkOperation *completedOperation) { //得到返回的JSON字符串 NSMutableDictionary *responseDictionary = [completedOperation responseJSON]; //得到字符串中的menuitems的子节点的内容 NSMutableArray *menuItemsJson = [responseDictionary objectForKey:@"menuitems"]; NSMutableArray *menuItems = [NSMutableArray array]; //遍历节点, [menuItemsJson enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { //然后将其中的key-value 通过 initWithDictionary 给类的属性赋值 [menuItems addObject:[[MenuItem alloc] initWithDictionary:obj]]; }]; succeedBlock(menuItems); } onError:errorBlock]; [self enqueueOperation:op]; return op;}
Demo 下载地址:iHotelAPP
0 0
- 第十四章 REST解惑——初识KVC
- 第十四章 REST解惑——REST简介
- 第十四章——UINavigationController
- 解惑REST架构
- KVO/KVC系列——KVC编程
- 第十四章——转换操作符
- 汇编语言——第十四章(端口)
- 编程珠玑第十四章—堆
- oc——KVC
- Java环境下SOE—Rest开发之1(初识)
- 【REST-Framework 】初识
- 创建博客-初识REST
- Django Rest Framework - 初识
- 讨论——解惑
- Java——解惑
- KVO/KVC系列之一——什么是KVC
- KVO/KVC系列之二——KVC编程
- 深入理解 KVC\KVO 实现机制 — KVC
- windows 查看端口 停止占用端口
- HDU4530
- Gitolite 构建 Git 服务器
- DOS和Linux常用命令的对比
- Count on Cantor
- 第十四章 REST解惑——初识KVC
- 关于schedule_timeout
- Android_文字、图片自适应设备屏幕分辨率
- 通过firefox插件firebug获取webqq群和群成员的javascript脚本(转)
- Java Collections Framework之HashMap源码分析(基于JDK1.6)
- 面经&感想
- 转【上古秘籍】之Eclipse的秘籍
- CS菜鸟找小公司software engineer工作记
- 闹钟开发过程中用PendingIntent传送数据丢失解决办法