iOS-KVC(二)内部赋值深层次原理

iOS-KVC(一)基本使用
iOS-KVC(二)内部赋值深层次原理
iOS-KVC(三)内部取值深层次原理
iOS-KVC(四)常见异常处理
iOS-KVC(五)容器类
iOS-KVC(六)正确性验证
iOS-KVC(七)字典相关
iOS-KVC(八)常见使用

主要涉及到的这个方法

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

当用以上方法时候,底层的执行机制如下

注意:一下代表的是属性的名称,比如

@property (nonatomic, copy) NSString *name;

那么表示如下,区分大小写
:Name
:name
  1. 优先调用-set:方法,通过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: '[ setNilValueForKey]: could not set nil as the value for the key age.'
  1. 如果没有找到-set:方法,KVC会检查
+ (BOOL)accessInstanceVariablesDirectly

方法返回值,默认是返回YES。

  • 返回NO
    如果你重写了这个方法,并且返回NO,那么下一步KVC将会执行
- (void)setValue:(id)value forUndefinedKey:(NSString *)key
  • 返回YES
    会根据以下顺序查找
    _, _is, , is,无论该变量是在类接口处定义,还是在类实现处定义,也无论用了什么样的访问修饰符,KVC都可以对其赋值。
  1. 如果上面都没有查找到,那么就执行该对象的
- (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
````·

你可能感兴趣的:(iOS-KVC(二)内部赋值深层次原理)