KVC/KVO原理及应用(上)

本文参考博客http://blog.youkuaiyun.com/ajrm0925/article/details/7484678,未尽之处可到原博客中查找

一、KVC的原理

KVC运用了一个isa-swizzling技术,并且通过isa-swizzling来实现其内部查找定位的。简单讲 ,在编译时KVC会被进行如下编译:

//编译前
[obj setValue:@"objName" forKey:@"name"]
//编译后
SEL sel = sel_get_uid ("setValue:forKey:");
IMP method = objc_msg_lookup (obj->isa,sel);
method(obj, sel, @"objName", @"name");

上面的三个方法可以理解为
1. 用sel_get_uid方法,通过字符串获得方法的指针
2. 用objc_msg_lookup方法,用isa指针到对象所属的类中,通过方法指针找到方法
3. 调用方法赋值

二、KVC的应用
1. 重写setValue:forKey

在字典转模型中,如果字典中的key有id这个关键字,直接转模型时会报警告,为了解决这个警告,我们可以重写setValue:forKey:

- (void)setValue:(id)value forKey:(NSString *)key
{
    if ([key isEqualToString:@"id"]) {
        [self setValue:value forKeyPath:@"ID"];
    }else{
        [super setValue:value forKey:key];

    }
}
2. 基本的赋值取值
[book setValue:@"《乔布斯传》" forKey:@"name"]; 
NSString *name=[book valueForKey:@"name"];
3. 使用路径

可以通过点语法取值

@interface Author : NSObject { 
    NSString *name; 
}
@end

#import "Author.h"
@implementation Author
@end

@class Author;
@interface Book : NSObject { 
    NSString *name; 
    Author *author; 
}
@end

Book *book=[[[Book alloc] init] autorelease]; 
[book setValue:@"《乔布斯传》" forKey:@"name"]; 
NSString *name=[book valueForKey:@"name"]; 

Author *author=[[[Author alloc] init] autorelease]; 
[author setValue:@"Walter Isaacson" forKey:@"name"]; 
[book setValue:author forKey:@"author"]; 
NSString *authorName=[book valueForKeyPath:@"author.name"];
4. 自动装箱拆箱

即可以用基本数据类型接收传入的字符串类型,也可以用字符串类型直接打印取出来的基本数据类型。

5. 对数组的操作
Book *book =[[[Book alloc] init] autorelease]; 
Book *book1=[[[Book alloc] init] autorelease]; 
[book1 setValue:@"5.0" forKey:@"price"]; 
Book *book2=[[[Book alloc] init] autorelease]; 
[book2 setValue:@"4.0" forKey:@"price"]; 
NSArray *books=[NSArray arrayWithObjects:book1,book2,nil]; 
[book setValue:books forKey:@"relativeBooks"]; 
NSLog(@"relative books price: %@",[book valueForKeyPath:@"relativeBooks.price"]);
6. 为实例的多个属性赋值
Book *book4=[[Book alloc] init]; 
NSArray *bookProperties=[NSArray arrayWithObjects:@"name",@"price",nil]; 
NSDictionary *bookPropertiesDictionary=[book4 dictionaryWithValuesForKeys:bookProperties]; 
NSLog(@"book values: %@",bookPropertiesDictionary);
NSDictionary *newBookPropertiesDictionary=[NSDictionary dictionaryWithObjectsAndKeys:@"《Objective C入门》",@"name", @"20.5",@"price",nil]; 
[book4 setValuesForKeysWithDictionary:newBookPropertiesDictionary]; 
NSLog(@"book with new values: %@",[book4 dictionaryWithValuesForKeys:bookProperties]);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值