KVC

KVC KVO

KVC NSKeyValueCoding 的缩写,它是Foundation Kit 中的一个NSObject Category,作用你可以类比JAVA 中的反射机制,就是动态访问一个对象中的属性。KVC 在解析key 的字符串的时候,是会比你正常调用settergetter 要慢的,而且编译器无法在编译器对你的方法调用做出检查(因为你的属性名都是字符串,只有运行时才会知道你有没有写错),出错的几率也会提高,所以请不要随意使用KVC,而省去settergetter 方法。KVC 一般用于动态绑定,也就是运行时才能确定谁调用哪个方法,编译期并不确定。


KVO就是NSKeyValueObserving的缩写,它也是Foundation Kit中的一个NSObjectCategoryKVO 基于KVC 实现,基于观察者设计模式(Observer Pattern)实现的一种通知机制,你可以类比JAVA 中的JMS,通过订阅的方式,实现了两个对象之间的解耦,但又可以让他们相互调用。(具体请查资料)


isa-swizzling

isa, is a kind of。

swizzling, 混合,搅合。

isa-swizzling就是类型混合指针机制。KVC主要通过isa-swizzling,来实现其内部查找定位的。


[site setValue:@"sitename" forKey:@"name"];

编译器处理成:

SEL sel = sel_get_uid ("setValue:forKey:");

IMP method = objc_msg_lookup (site->isa,sel);

method(site, sel, @"sitename", @"name");


isa指针,就是is a kind of的意思,指向维护分发表的对象的类。该分发表实际上包含了指向实现类中的方法的指针,和其它数据。

SEL数据类型:它是编译器运行Objective-C里的方法的环境参数。

IMP数据类型:他其实就是一个 编译器内部实现时候的函数指针。当Objective-C编译器去处理实现一个方法的时候,就会指向一个IMP对象,这个对象是C语言表述的类型。


KVC的基本概念

      1:键值编码是一个用于简介访问对象属性的机制,使用该机制不需要调用存取方法和变量实例

就可以访问对象属性。

      2:键值编码方法在Objective-C非正式协(类别)NSKeyValueCoding中被声明,默认的实现方法

由NSObject提供。

      3:键值编码支持带有对象指的属性,同时也支持数值类型和结构。非对象参数和返回类型会被

识别并自动封装/解封。

KVC-设置与访问:

       键值编码洪的基本调用包括-valueForKey:和setValue:forKey:这两个方法,他们以字符串的形式

向对象发送消息,字符串是我们关注属性的关键,看下面的一个设置和访问的例子:

<span style="font-size:14px;">@interface Author : NSObject
@property (nonatomic,copy)NSString *title;
@end
@implementation Author
@end

@interface Person : NSObject
@property (nonatomic,copy)NSString *name;
@property (nonatomic,retain)Author *author;
@property (nonatomic,retain)NSMutableArray *persons;
@property (nonatomic,assign)NSInteger age;
@end

@implementation Person
@end</span>
<span style="font-size:14px;"> Person *person=[[Person alloc]init];
    NSMutableString *name=[[NSMutableString alloc]initWithString:@"张三"];
    [person setValue:name forKey:@"name"];
    NSLog(@"张三 name :%@",[person valueForKey:@"name"]);//张三 name :张三</span>

首先去检查是否存在setter,getter方法,如果不存在,它将在内部查找名_key或key的实例变量。如果还是没有那就会报错误(

setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key ***.)。通过KVC可以获取不存在getter方法的对象值,无需通过对象指针直接访问。

【注意】:当我们通过setValue:forKey:设置对象的值,或者valueForKey:来获取对象的值时,如果对

象的实例变量为基本数据类型时(例如:char,int,float,BOOL),我们需要对这些数据类型进行封装。

KVC-路径:

      除了上面通过键值进行设置和访问意外,键值还支持指定路径,像文件一样。用"."号隔开。实例如下:

    Person *person=[[Person alloc]init];
    Author *auther=[[Author alloc]init];
    [auther setValue:@"IOS开发" forKey:@"title"];
    NSMutableString *name=[[NSMutableString alloc]initWithString:@"张三"];
    [person setValue:name forKey:@"name"];
    [person setValue:auther forKey:@"author"];
    NSLog(@"name :%@",[person valueForKey:@"name"]);//name :张三
    NSString *title=[person valueForKeyPath:@"author.title"];
    NSLog(@"title :%@",title);//title :IOS开发

KVC-一对多关系:

        如果向NSArray请求一个键值,它实际上回查询数组中的每个对象来查找这个键值,然后将查询结果

打包到另一个数组中并返回给你。实例如下:           

    //一对多关系
    Person *person=[[Person alloc]init];
    NSMutableArray *persons=[NSMutableArray arrayWithCapacity:3];
    for(int i=0;i<3;i++){
        Person *per=[[Person alloc]init];
        NSString *name=[NSString stringWithFormat:@"person_%d",i];
        per.age=i*10;
        [per setValue:name forKey:@"name"];
        [persons addObject:per];
        [per release];
    }
    [person setValue:persons forKey:@"persons"];
    NSArray *nameArray= [person valueForKeyPath:@"persons.name"];
    NSLog(@"%@",nameArray);
    /*
     2014-01-22 11:07:03.381 Production[1245:90822] (
       "person_0",
       "person_1",
       "person_2"
      )
     */

KVC的简单运算:

      此外,还可以应用一些字符做简单运算。sum,min,max,avg,count

 //属性相加
    NSString *sum= [person valueForKeyPath:@"persons.@sum.age"];
    NSLog(@"sum = %@",sum);
    //数量
    NSString *count= [person valueForKeyPath:@"persons.@count.age"];
    NSLog(@"count = %@",count);
    //最大值
    NSString *max= [person valueForKeyPath:@"persons.@max.age"];
    NSLog(@"max = %@",max);
    //最小值
    NSString *min= [person valueForKeyPath:@"persons.@min.age"];
    NSLog(@"min = %@",min);
    //平均值
    NSString *avg= [person valueForKeyPath:@"persons.@avg.age"];
    NSLog(@"avg = %@",avg);
//    2014-01-22 11:07:03.385 Production[1245:90822] sum = 30
//    2014-01-22 11:07:03.385 Production[1245:90822] count = 3
//    2014-01-22 11:07:03.385 Production[1245:90822] max = 20
//    2014-01-22 11:07:03.386 Production[1245:90822] min = 0
//    2014-01-22 11:07:03.386 Production[1245:90822] avg = 10


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值