iOS-KVC(二)内部赋值深层次原理
2019-06-23 本文已影响0人
厦门_小灰灰
iOS-KVC(一)基本使用
iOS-KVC(二)内部赋值深层次原理
iOS-KVC(三)内部取值深层次原理
iOS-KVC(四)常见异常处理
iOS-KVC(五)容器类
iOS-KVC(六)正确性验证
iOS-KVC(七)字典相关
iOS-KVC(八)常见使用
主要涉及到的这个方法
- (void)setValue:(nullable id)value forKey:(NSString *)key;
当用以上方法时候,底层的执行机制如下
注意:一下<Key>代表的是属性的名称,比如
@property (nonatomic, copy) NSString *name;
那么表示如下,区分大小写
<Key>:Name
<key>:name
- 优先调用-set<Key>:方法,通过setter方法完成设置。
注:如果设置的值是nil,并且key的指向的属性或者成员变量为非对象类型时,会执行-setNilValueForKey: ,然后抛出一个异常。
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) NSInteger age;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//为name赋值为nil
[self setValue:nil forKey:@"name"]; //设置值
//为age赋值为nil
[self setValue:nil forKey:@"age"]; //设置值
}
@end
结果:
为name赋值为nil,没有异常。
为age赋值为nil,抛出异常,如下
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '[<ViewController 0x7fa064614bb0> setNilValueForKey]: could not set nil as the value for the key age.'
- 如果没有找到-set<Key>:方法,KVC会检查
+ (BOOL)accessInstanceVariablesDirectly
方法返回值,默认是返回YES。
- 返回NO
如果你重写了这个方法,并且返回NO,那么下一步KVC将会执行
- (void)setValue:(id)value forUndefinedKey:(NSString *)key
- 返回YES
会根据以下顺序查找
_<key>, _is<Key>, <key>, is<Key>,无论该变量是在类接口处定义,还是在类实现处定义,也无论用了什么样的访问修饰符,KVC都可以对其赋值。
- 如果上面都没有查找到,那么就执行该对象的
- (void)setValue:(id)value forUndefinedKey:(NSString *)key
方法,默认是抛出异常-NSUndefinedKeyException。
简单示例:
- +(BOOL)accessInstanceVariablesDirectly 返回YES
#import "ViewController.h"
@interface ViewController ()
{
NSString *_name;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//_name,其余的可以自己尝试
[self setValue:@"hui" forKey:@"name"];
NSLog(@"_name=%@", _name);
//故意填写不存的key值
[self setValue:@"123" forKey:@"123"];
}
+(BOOL)accessInstanceVariablesDirectly
{
return YES; //默认值返回的是YES
}
- (void)setValue:(id)value forUndefinedKey:(NSString *)key
{
NSLog(@"当前找不到对应的key=%@", key);
}
@end
结果:
2019-06-22 22:08:10.568625+0800 study[9669:146687] _name=hui
2019-06-22 22:08:10.568866+0800 study[9669:146687] 当前找不到对应的key=123
- +(BOOL)accessInstanceVariablesDirectly 返回NO
代码就不贴出,跟上面几乎一样。
结果:
2019-06-22 22:10:01.072808+0800 study[9728:147664] 当前找不到对应的key=name
2019-06-22 22:10:01.072975+0800 study[9728:147664] _name=(null)
2019-06-22 22:10:01.073106+0800 study[9728:147664] 当前找不到对应的key=123
````·