ios-KVC深入

KVC全称Key Value Coding也就是键值编码,当在同时实现setter和getter时,类中的@property不会自动生成带下滑线的成员变量,而我们如果去定义了一个带下划线的成员变量NSString * _bookName; 然后我们在外面使用的时候[stu setValue:@"kkk" forKey:@"_bookName"]; 也是已经给bookName赋值了,,因为Xcode会默认将self.bookName与自定义成员变量_bookName关联。

当然如果我们直接使用@synthesize bookName = _bookName; 然后在外面用KVC对_bookName赋值的话也是可以赋值的,因为写了这句话之后其实就相当于是把bookName和_bookName给联系起来了。

当然如果我们采取@synthesize bookName = _obj; 一样在外面通过KVC给_obj设置值一样会关联到bookName。

一般来说在KVC中我们使用了ValueForKey想去寻找key对应的值的话,会先去找相关的方法,再去找相关的变量。

如果说我们相关的方法找不到的时候,才会去找相关的变量,这点可以在下面中进行证明,当我们定义了下面这样的属性

@property (nonatomic ,strong)NSString *name;
//以及我们写了下面这个方法
-(NSString *)getName
{
    _name=@"qqq";
    return @"kkdjskja";
}
//然后根据key是name去获取值,获取到的是kkdjskja,而我们打印student的name是qqq

 NSString * str = [student valueForKey:@"name"];

还有需要了解的是,如果我们的属性是有用readonly修饰的,并且实现了下面的这个方法,那么我们是无法用KVC给这个属性赋值的,这个方法默认返回 YES,也就是说在不存在满足条件的方法时,允许直接访问属性对应的实例变量,如果我们返回NO就表示不允许访问。但如果去掉readonly还是可以赋值的。

以及我们在使用[student setValue:@"qweqwe" forKey:@"name"];赋值的时候回优先去找setName的方法,如果找不到方法然后再去找成员变量,然后再去赋值。当然这个前提是下面的这个方法要返回YES。

+(BOOL)accessInstanceVariablesDirectly
{
    return NO;
}


还有就是我们在类扩展中定义的变量也是无法通过KVC进行赋值的,如果我们上面的这个方法也返回了NO。

@interface Student()
{
   NSString * name;
}

当然也无法通过valueForKey去访问它的值。去寻找相应的Value是优先去找get<Key>然后再去找<key>方法。

还有就是当我们有一个变量是基本数据类型的时候,使用valueForKey会帮我们转换成NSNumber类型。

如果我们定义的是成员变量NSString * _name;则我们在使用setValue ForKey赋值的时候可能会调用两个方法,如果两个方法都实现了就只会调用优先级高的也就是setName方法

优先级低的是setIsName方法。但如果我们定义的是属性name,如果去使用KVC赋值的时候以及只实现了setIsName方法也不会去调用setIsName方法。

-(void)setName:(NSString *)name
{
    NSLog(@"dadaokiji");
}
-(void)setIsName:(NSString *)name
{
    NSLog(@"12131");
}

我们如果在一个类中有这些成员变量的话,那么赋值的过程是有顺序的,如下所示,比如说我们通过valueForKey:@"name"去获取值,获取到的顺序如下所示,也就是说如果不存在满足条件的方法,以及+ (BOOL)accessInstanceVariablesDirectly 返回 YES,那么就会以 _<key> , _is<Key> , <key> , is<Key> 的顺序查找是否存在对应的key。

    NSString * isName;//4
    NSString * _isName;//2
    NSString * name;//3
    NSString * _name;//1
还有一个就是我们如果再类的内部有一个属性是大写开头的比如说Nook,我们在外部用KVC把key设置成nook也是可以赋值的。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值