您的位置:首页 > 移动开发 > IOS开发

iOS KVC和一些基础知识了解

2016-03-04 14:48 471 查看
字典和模型都用来存储数据 .
字典 :
通过字符串类型的key取值.(一般情况下,设置数据和取出数据都使用"字符串类型的key",编写这些key时,编译器不会有任何友善提示,需要手动敲写.手动敲写字符串key,key容易写错,且如果写错,编译器不会有任何警告和报错,容易造成设错数据或者取错数据)

模型类 , 即用来存放数据的类, 继承自NSObject.
所谓模型,其实就是数据模型, 专门用来存放数据的对象,用它来表示会更加专业.
模型设置数据和取出数据都是通过它的属性, 属性名如果写错,编译器会马上报错,因此保证了数据的正确性.

使用模型访问属性时, 编译器会提供一系列的提示,提高编码效率.

字典转模型应该提供一个可以传入字典参数的构造方法. 一般提供如下两个方法(一个对象方法和一个类方法) , 为了与苹果公司原代码保持一致性,方法名称尽量模仿苹果公司规范来书写.
-(instancetype)initWithDict:(NSDictionary *)dict;
+(instancetype)XXXWithDict:(NSDictionary *)dict;

instancetype:在类型表示上,跟id一样,可以表示任何数据类型;
instancetype只能用在返回值类型上,不能像id一样用在参数类型上;
instancetype比id多一个好处:编译器会检测instancetype的真实类型.
根据数据字典的键值对,创建对应的数据模型. 在.h文件中声明模型属性及方法 .如下

#import <Foundation/Foundation.h>
@interface MJApp : NSObject
/** * 名称 */
@property (nonatomic, copy) NSString *name;/
** * 图标 */
@property (nonatomic, copy) NSString *icon;
/** * 标题 */
@property (nonatomic, weak) NSString *title;
/** * 答案 */
@property (nonatomic, copy) NSString *answer;
/** * 通过字典来初始化模型对象 * * @param dict 字典对象 * * @return 已经初始化完毕的模型对象 */
- (instancetype)initWithDict:(NSDictionary *)dict;
+ (instancetype)appWithDict:(NSDictionary *)dict;@end

注意:@property是一个属性访问申明,括号内支持以下属性:
1> getter = getterName;setter = setterName,设置setter与getter的方法名.
2> readwrite:同时生成get方法和set方法的声明和实现;

3> readonly:只生成get方法的声明是实现;
· readwrite与readonly,都是设置访问级别.
4> assign: set方法的实现是直接赋值,不进行任何retain操作,为了解决原类型与循环引用问题,一般用于基本数据类型;
5> retain:set方法的实现的release旧值,retain新值,用于OC对象类型;
6> copy: set方法的实现是release旧值,copy新值,用于NSString block等类型;
7> nonatomic:非原子性访问,不加同步,多线程并发访问会提高性能.如果不加此属性,则默认两个访问方法都为原子型事物访问.锁被加到所属对象实例级.set方法的实现不加锁(比atpmic性能高).
8> strong: 用于一般对象
9> weak: 用于UI控件, 如UIButton , UILable等
字典转模型实现方法如下:

#import "MJApp.h"
@implementation MJApp
- (instancetype)initWithDict:(NSDictionary *)dict{
if (self = [super init]) {
self.name = dict[@"name"];
self.icon = dict[@"icon"];
self.title = dict[@"title"];
self.answer = dict[@"answer"]; }
return self;
}
+ (instancetype)appWithDict:(NSDictionary *)dict{
return [[self alloc] initWithDict:dict];}
@end

或者用KVC方法来实现

#import "MJApp.h"
@implementation MJApp
- (instancetype)initWithDict:(NSDictionary *)dict{
if (self = [super init]) { [self setValuesForKeysWithDictionary:dict]; }
return self;
}
+ (instancetype)appWithDict:(NSDictionary *)dict
{
return [[self alloc] initWithDict:dict];
}
@end

但是KVC的使用是有条件的 ; 由于KVC会将字典所有的键值对(key-value)赋值给模型对应的属性.只有当字典的键值对个数跟模型的属性个数相等,并且属性名必须和字典的键值对一样时才可以使用KVC.

/** * 字典转模型,模型再次存入数组中 重写数组的set方法 */
-(NSArray *)questions{ if (_questions ==nil) {
//加载plist,将plist中存储的字典数据放在数组dictArray中
NSArray *dictArray = [NSArray arrayWithContentsOfFile:
[[NSBundle mainBundle] pathForResource:@"questions.plist" ofType:nil]];
NSMutableArray *questionArray = [NSMutableArray array];
//用自定义的JNQuestion模型question来接收 数组 dictArray 中的元素;
for (NSDictionary * dict in dictArray){
JNQuestions *question = [JNQuestions questionWithDict:dict];
//JNQuestions *question =[[JNQuestions alloc]initWithDict:dict];
[questionArray addObject:question];
}
// 赋值
_questions = questionArray;
}
return _questions; }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: