Object-C KVC模式使用详解(一)

来源:互联网 发布:js添加点击事件请求url 编辑:程序博客网 时间:2024/04/24 00:36

Object-C KVC模式使用详解(一)

1 除了一般的赋值和取值方法,我们还可以用key —-value——Coding(KVC)键值编码来访问你要存取的类的属性


2:KVC常用的方法


-(void)setValue:(id)value forKey:(NSString *)key;


-(id) valueForKey:(NSString *)key;


- (void)setValue:(id)value forUndefinedKey:(NSString *)key


-(void)setValue:(id)value forKeyPath:(NSString *)keyPath;


-(id)valueForKeyPath:(NSString *)keyPath;

KVC通过字符串的key或者keyPath定位对象的属性.


(1) 若不存在此key,会调用 valueForUndefinedKey:.他的默认实现会抛出NSUndefinedKeyException,子类可以通过复写valueForUndefinedKey方法来进行相应的提示信息.

(2) 尝试给一个非对象类型设置nil,对象默认调用setNilValueForKey方法抛出NSInvalidArgumentException

(3)l鉴权机制validatePersonName


Student.h


@interface Student : NSObject

@property(nonatomic,copy)NSString *name;

@property(nonatomic,copy)NSString *Name;

@property(nonatomic,assign)NSInteger Age;

@end


Student.m

@implementation Student

//通过重写该方法,来实现自己的设置逻辑

- (void)setValue:(id)value forKey:(NSString *)key

{

    NSLog(@"自定义存储逻辑");

}

//通过重写该方法,来实现自己的设置逻辑

- (void)setValue:(id)value forUndefinedKey:(NSString *)key

{

    NSLog(@"forUndefinedKey:没有找到相应的%@",key);

   NSLog(@"%@", key);

}

//(1)当以放法valueForKey查找key,若没找到则调用此方法

- (id)valueForUndefinedKey:(NSString *)key{


    NSLog(@"valueForUndefinedKey:没有找到相应的%@",key);

    return nil;

}

//(2)当给一个非对象內型设置为 "nil",调用此方法

- (void)setNilValueForKey:(NSString *)key{

    NSLog(@"setNilValueForKey");


}

@end


main.h

[stu setValue:@"46345"forKey:@"name"];

NSString *string = [stuvalueForKey:@"luo”];调用(1)方法

[stusetValue:nilforKey:@"Age”];调用(2)方法


3:使用KVC - (void)setValue:(id)value forKey:(NSString *)key方法赋值需要注意的地方

(1) 系统默认的setValue方法在方法内部是不区分大小写的

列如如下操作:

[stusetValue:@"46345"forKey:@“Name"];

main函数中打印Name的值:

NSLog(@"Name = %@",stu.Name);

NSLog(@"name = %@",stu.name);

打印如下:

2015-07-17 05:38:41.322 OC04_属性[2375:213898] Name = (null)

2015-07-17 05:38:41.323 OC04_属性[2375:213898] name = 46345

(2)为何我给Name赋值,Name = nil;name = 46345?

原因:

-(void)setValue:(id)value forKey:(NSString *)key

{

   for (<#initialization#>; <#condition#>; <#increment#>) {

       if (<#condition#>) {

           break;

        }

    }

}

这相当于系统内部函数的实现机制,一个for循环,一个if语句,当找到与key相关的属性(方法内部是不区分大小写的)就会break;当碰到一个和key相匹配的时候就直接返回.

KVC访问属性的几点原则:

①检查是否存在-<key>-is<key>(只针对布尔值有效)或者-get<key>的访问器方法,如果有可能,就是用这些方法返回值; 

检查是否存在名为-set<key>:的方法,并使用它做设置值。对于-get<key>-set<key>:方法,将大写Key字符串的第一个字母(这就是我上面产生错误的原因),并与Cocoa的方法命名保持一致; 

②如果上述方法不可用,则检查名为-_<key>-_is<key>(只针对布尔值有效)、-_get<key>-_set<key>:方法; 

③如果没有找到访问器方法,可以尝试直接访问实例变量。实例变量可以是名为:<key>_<key>; 

④如果仍为找到,则调用valueForUndefinedKey:setValue:forUndefinedKey:方法。这些方法的默认实现都是抛出异常,我们可以根据需要重写它们。


若我这样写则不会出现上面的情况:

@property(nonatomic,copy)NSString *name;

@property(nonatomic,copy)NSString *NAme;

[stu setValue:@"46345"forKey:@"NAme"];

   NSLog(@"NAme = %@",stu.NAme);

    NSLog(@"name = %@",stu.name);

打印如下:

2015-07-17 16:37:21.880 OC04_属性[436:12514] NAme = 46345

2015-07-17 16:37:21.881 OC04_属性[436:12514] name = (null)




1 0
原创粉丝点击