Objective-C之KVC

来源:互联网 发布:淘宝衣服是死人衣服吗 编辑:程序博客网 时间:2024/05/16 12:13

KVC

可以访问私有变量

KVC-键值编码的基本概念

KVCKey Value Coding的简称,它是一种可以直接通过字符串的名字(key)来访问类属性的机制。使用该机制不需要调用存取方法和实例就可以访问对象属性,本质上讲,键-值编码定义了你程序存取方法需要实现的样式及方法签名
KVC的操作方法由NSKeyValueCoding协议提供,而NSObject就实现了这个协议,也就是说ObjC中几乎所有的对象都支持KVC操作
常用的KVC操作方法
动态设置
setValue:属性值forKey:属性名(用于简单路径
setValue:属性值forKeyPath:属性路径(用于复合路径,例如Person有一个Account类型的属性,那么person.account就是一个复合属性)
动态读取: 
valueForKey:属性名
valueForKeyPath:属性名(用于复合路径)
KVC使用规则
KVC使用起来比较简单,但是它如何查找一个属性进行读取呢?具体查找规则(假设现在要利用KVCa进行读取)
如果是动态设置属性,则优先考虑调setA方法;
如果没有该方法则优先考虑搜索成员变量_a
如果仍然不存在则搜索成员变量a
如果最后仍然没搜索到则会调用这个类setValue:forUndefinedKey方法(注意搜索过程中不管这些方法、成员变量是私有的还是公共的都能正确设 置)
KVC使用规则
如果是动态读取属性:
则优先考虑调a方法(属性agetter方法);
如果没有搜索到则会优先搜索成员变量_a
如果仍然不存在则搜索成员变量a
如果最后仍然没搜索到则会调用这个类valueforUndefinedKey:方法(注意搜索过程中不管这些方法、成员变量是私有的还是公共的都能正确 读取)
KVC-键值路径
[author valueForKeyPath:@"issueBook.price"]
[author valueForKeyPath:@"issueBook.@count"]
[author valueForKeyPath:@"issueBook.@sum.price"]
[author valueForKeyPath:@"issueBook.@avg.price"]
[author valueForKeyPath:@"issueBook.@max.price"]
[author valueForKeyPath:@"issueBook.@min.price"]


Person类

#import <Foundation/Foundation.h>#import "Account.h"@interface Person : NSObject{@private int _age;//成员变量         int age;    }@property(nonatomic,copy)NSString *name;@property(nonatomic,retain)Account *account;@end

.m文件

#import "Person.h"@implementation Person-(void)setValue:(id)value forUndefinedKey:(NSString *)key{    NSLog(@"设置失败!!");}-(id)valueForUndefinedKey:(NSString *)key{    NSLog(@"没有此key!");    return 0;}@end

Account类
#import <Foundation/Foundation.h>@interface Account : NSObject@property(nonatomic,assign)float balance;@end

main文件
#import <Foundation/Foundation.h>#import "Person.h"#import "Account.h"int main(int argc, const char * argv[]) {       Person *p = [[Person alloc]init];    Account *a = [[Account alloc]init];    //进行赋值    [a setValue:@"16.5" forKey:@"balance"];//必须保证key不被写错    //进行取值    NSLog(@"account =%@",[a valueForKey:@"balance"]);        [p setValue:@"tom" forKey:@"name"];    NSLog(@"p.name = %@",[p valueForKey:@"name"]);   //将对象赋值给a里的对象    [p setValue:a forKey:@"account"];     //[id valueForKeyPath@"String"]通过路径设置取值    NSLog(@"p.account.balance = %@",[p valueForKeyPath:@"account.balance"]);       //对私有变量的赋值与访问    [p setValue:@"18" forKey:@"_age"];    NSLog(@"p._age = %@",[p valueForKey:@"_age"]);    //此处的age并不是私有变量    [p setValue:@"21" forKey:@"age"];    NSLog(@"p.age = %@",[p valueForKey:@"age"]);        //对p中a.balance赋值 取值 [id setValue(id)value forKeyPath(NSString *)path]    [p setValue:@"45000.5" forKeyPath:@"account.balance"];    NSLog(@"account.balance = %@",[p valueForKeyPath:@"account.balance"]);       //下面是key值错误的情况://    [a setValue:@"200" forKey:@"wrongKey"];//    NSLog(@"a.balance = %@",[a valueForKey:@"wronKey"]);    //程序直接出错了,但是通过在对应类的.m文件对-(void)setValue:(id)value forUndefinedKey:(NSString *)key;-(id)valueForUndefinedKey:(NSString *)key方法进行重写,可以让程序正确运行。    //下面是Person类中重写了这两方法后给出的提示        [p setValue:@"20" forKey:@"wrongKey"];    NSLog(@"这是错误的取出key%@",[p valueForKey:@"wrongKey"]);        return 0;}




0 0
原创粉丝点击