iOS技术点iOS重点知识汇总

iOS KVC (二) 不可不知的赋值深层次原理

2018-05-16  本文已影响74人  奔跑吧小蚂蚁

iOS KVC(一)基本了解
iOS KVC (二) 不可不知的赋值深层次原理
iOS KVC (三)不可不知的取值深层次原理
iOS KVC (四)keyPath的深度解析
iOS KVC (五)KVC几种典型的异常处理
iOS KVC (六) KVC容器类及深层次原理
iOS KVC(七) KVC正确性的验证
iOS KVC (八) KVC几种常见应用
iOS KVC (九) KVC模型转化(1) 模型打印 description, debugDescription
iOS KVC (十)模型转换(2)模型转换

KVC赋值

赋值的过程看似很简单,就是找到对应的key,然后将一个已经准备好的值赋过去,但是你知道深层次的原理吗?方法- (nullable id)valueForKey:(NSString *)key;中的key系统内部和底层是按照什么逻辑找的呢?下面就让我们看一下。

下面就是寻找key的内部流程。以[self setValue:@"小明" forKey:@"name"];这句代码作为例子进行说明。

下面结合例子进行说明

+ (BOOL)accessInstanceVariablesDirectly 返回NO实例

实例

#import "ViewController.h"
@interface ViewController ()
@end

@implementation ViewController
{
    NSString *name;
}
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    [self setValue:@"小明" forKey:@"name"];
    NSLog(@"name = %@", name);
}
+ (BOOL)accessInstanceVariablesDirectly
{
    return NO;
}

- (void)setValue:(id)value forUndefinedKey:(NSString *)key
{
    NSLog(@"没有找到该key对应的属性会抛出异常");
}

打印数据:
2018-05-16 14:45:42.959735+0700 KVC[21922:462925] 没有找到该key对应的属性会抛出异常
2018-05-16 14:45:42.959850+0700 KVC[21922:462925] name = (null)

总结:这里+ (BOOL)accessInstanceVariablesDirectly返回了NO,也就是说找不到属性的setter方法,那么不会再去找实例变量,所以会输出上面的结果。所以name输出结果就是null。

+ (BOOL)accessInstanceVariablesDirectly 返回YES实例

accessInstanceVariablesDirectly 默认返回YES。

实例1 self.name

#import "ViewController.h"
@interface ViewController ()
@property (nonatomic,strong)NSString *name;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    [self setValue:@"小明" forKey:@"name"];
    NSLog(@"self.name = %@", self.name);
}

实例2 name

#import "ViewController.h"
@interface ViewController ()
@end

@implementation ViewController
{
    NSString *name;
}
- (void)viewDidLoad {
    [super viewDidLoad];
    [self setValue:@"小明" forKey:@"name"];
    NSLog(@"name = %@", name);
}

打印数据:
2018-05-16 14:53:45.648667+0700 KVC[22042:467903] name = 小明

实例3 _name

#import "ViewController.h"
@interface ViewController ()

@end

@implementation ViewController
{
    NSString *_name;
}
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    [self setValue:@"小明" forKey:@"name"];
    NSLog(@"_name = %@", _name);
}
打印数据:
2018-05-16 14:57:03.714227+0700 KVC[22107:470305] _name = 小明

实例4 _isName

#import "ViewController.h"
@interface ViewController ()

@end

@implementation ViewController
{
    NSString *_isName;
}
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    [self setValue:@"小明" forKey:@"name"];
    NSLog(@"_isName = %@", _isName);
}
打印数据:
2018-05-16 14:58:24.632017+0700 KVC[22153:471747] _isName = 小明

实例5 isName

#import "ViewController.h"
@interface ViewController ()

@end

@implementation ViewController
{
    NSString *isName;
}
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    [self setValue:@"小明" forKey:@"name"];
    NSLog(@"isName = %@", isName);
}
打印数据:
2018-05-16 15:00:53.388740+0700 KVC[22223:474376] isName = 小明

下面就是我们这个属性和实例变量的调用顺序。

上面的顺序亲测,是按照所列顺序执行的。

上一篇 下一篇

猜你喜欢

热点阅读