KVC知识点

1、KVC简介

KVC的全称是Key-Value Coding,俗称“键值编码”,可以通过一个key来访问某个属性

常见的API有:
//设置属性值
- (void)setValue:(id)value forKeyPath:(NSString *)keyPath;
- (void)setValue:(id)value forKey:(NSString *)key;
//获取属性值
- (id)valueForKeyPath:(NSString *)keyPath;
- (id)valueForKey:(NSString *)key; 
2、探究KVC本质

创建文件MJPerson.h

#import <Foundation/Foundation.h>

@interface MJPeroson : NSObject
//1.这样直接定义变量,在没有set、get方法的时候,会按照_age、_isAge、age、isAge的方法去查找成员变量
{
    int _age;
    int _isAge;
    int age;
    int isAge;
}

//2.这种定义属性,会自动生成对应的set方法和get方法
//@property(nonatomic,assign) int age;

@end

创建文件MJPerson.m

#import "MJPeroson.h"

@implementation MJPeroson

-(void)setAge:(int)age{
  //  _age = age;//这句代码不写,值不会改变,但是依然会触发KVO
    NSLog(@"执行setAge方法");
}

-(void)_setAge:(int)age{
//  _age = age;//这句代码不写,值不会改变,但是依然会触发KVO
    NSLog(@"执行_setAge方法");
}

+(BOOL)accessInstanceVariablesDirectly{
    //这个类方法是默认YES,在MJPerson类alloc的时候会执行
    //返回NO表示,不允许直接访问成员变量,接抛出异常
    //返回YES表示,允许直接访问成员变量,按照_age、_isAge、age、isAge的顺序去访问成员变量,如果以上四个成员变量都没有的话,也会抛出异常
    
    NSLog(@"执行accessInstanceVariablesDirectly方法");
    return YES;
}

@end

ViewController.m文件

#import "ViewController.h"
#import "MJPeroson.h"

@interface ViewController ()

@property(nonatomic,strong)MJPeroson *person;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.person = [[MJPeroson alloc] init];
    
    NSKeyValueObservingOptions options = NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld;
    [self.person addObserver:self forKeyPath:@"age" options:options context:nil];
}

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
//    这三种方法都可以成功设置self.person的age属性为10
//    [self.person setValue:@10 forKey:@"age"];
//    [self.person setValue:@(10) forKey:@"age"];
    [self.person setValue:[NSNumber numberWithInteger:10] forKey:@"age"];
}


-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
    NSLog(@"监听到%@的属性%@发生了变化----%@",object,keyPath,change);
}

-(void)dealloc{
    [self.person removeObserver:self forKeyPath:@"age"];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


@end

原理图如下:


屏幕快照 2018-10-04 下午2.41.28.png
屏幕快照 2018-10-04 下午2.39.56.png
3、总结:

<1>通过KVC修改属性会触发KVO么?
肯定会。
从上面也可以看出,当没有set方法的时候,使用KVC修改属性变量,KVO依然会触发,所以KVC内部应该也调用了willChangeValueForKey:key 和 didChangeValueForKey:key 方法,从而触发了KVO。

<2>KVC的赋值和取值过程是怎样的?原理是什么?
如上原理图所示

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • KVC KVC定义 KVC(Key-value coding)键值编码,就是指iOS的开发中,可以允许开发者通过K...
    jackyshan阅读 52,139评论 9 199
  • KVC和KVO 一、摘要 *1 KVO,即:Key-Value-Observing,它提供一种机制,当指定的对象的...
    浩杰ee阅读 1,855评论 0 5
  • KVC KVC定义 KVC(Key-value coding)键值编码,就是指iOS的开发中,可以允许开发者通过K...
    暮年古稀ZC阅读 6,530评论 2 9
  • 《招聘一个靠谱的 iOS》—参考答案(下) 说明:面试题来源是微博@我就叫Sunny怎么了的这篇博文:《招聘一个靠...
    Mominglaile阅读 4,938评论 0 1
  • KVC称为键值编码(key-value coding),从一个字符串名派生出一个访问器的名称。键(key)是一个字...
    清水一心阅读 3,008评论 0 1

友情链接更多精彩内容