KVC调用规则

每一天
原创文章,转载请注明:转自:Try_Try_Try

背景

关于KVC的使用方法,网络上已有很多文章介绍,这篇文章讲解的也很全面(https://www.jianshu.com/p/45cbd324ea65)。最近被问到了很多的问题,因此会将问到的问题都总结一下,方便之后查看。

很简单的一句话,描述一下kvc的get方法调用顺序?

嗯哼,我伙呆,当时就火大。

吐槽一下:感觉记住这个顺序用处不太大,可能当时记住了,之后就又忘了。我其实是比较反感问一些需要死记硬背,但是平时用处不太大的问题。如果当时有电脑,我直接可以进行演示操作,验证推倒。我直接说了句:忘了(对面坐的神 笑了一下,我内心开始不淡定,摸了摸后脑勺和鼻子,低下了头。)


目录结构:

    1. 代码结构简介
    • 1.1 类结构
    • 1.2 代码展示
    1. KVC中get调用顺序
    • 2.1 观察图片总结结论
    • 2.2 验证
    1. KVC中set调用顺序

正文:

因为我们对于图片都是敏感的,所以文章中尽量给出图片方便记忆(就像我开头放的那张小魔仙的图片一样,现在你一定还记得---内心笑一下吧)。

1. 代码结构简介

1.1 类结构
类结构
1.2 代码展示

其中Animate.h 和 Plant.h 的 实例变量是一样的。
Animate.h

#import <Foundation/Foundation.h>

// 记录get
@interface Animate : NSObject{
    
//    @public
//    NSString *_age;
//    NSString *_isAge;
//    NSString *age;
//    NSString *isAge;
}

@end

Animate.m

#import "Animate.h"

@implementation Animate


+ (BOOL)accessInstanceVariablesDirectly
{
    return YES;
}

- (NSString *)getAge
{
    NSLog(@"%@", NSStringFromSelector(_cmd));
    return @"1";
}

- (NSString *)age
{
    NSLog(@"%@", NSStringFromSelector(_cmd));
    return @"2";
}

- (NSString *)isAge
{
    NSLog(@"%@", NSStringFromSelector(_cmd));
    return @"3";
}

- (NSString *)_getAge
{
    NSLog(@"%@", NSStringFromSelector(_cmd));
    return @"4";
}

- (NSString *)_age
{
    NSLog(@"%@", NSStringFromSelector(_cmd));
    return @"5";
}

@end

Plant.h

#import <Foundation/Foundation.h>

// 记录set
@interface Plant : NSObject{
    
//        @public
//        NSString *_age;
//        NSString *_isAge;
//        NSString *age;
//        NSString *isAge;
}

@end

Plant.m

#import "Plant.h"

@implementation Plant

- (void)setAge:(NSString *)age
{
    NSLog(@"%@--%@", NSStringFromSelector(_cmd), age);
}

- (void)_setAge:(NSString *)age
{
    NSLog(@"%@--%@", NSStringFromSelector(_cmd), age);
}

@end

2. KVC中get调用顺序

好吧,先来一张图,说明执行的顺序,接着验证

2.1 观察图片总结结论
图片
图2.1 getValueForkey:

从上图2.1中可以看出基本的调用顺序,关于为什么是这个流程,其实通过断点验证出来的,并没有从源代码中发现其具体实现过程(关于这点,我一直在查找资料,毕竟要见到本质才相信)。

  • 右边的方法,左边的字段;(先调用方法,再执行字段)
  • 方法调用顺序:getKey、key、isKey、_getKey、_key
  • 字段调用顺序:_key、_isKey、key、isKey
2.2 验证

查看文件Animate相关内容
main.m中添加如下内容

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
        // get
        Animate *animate = [[Animate alloc] init];
        animate->_age = @"1";
        animate->_isAge = @"2";
        animate->age = @"3";
        animate->isAge = @"4";

        NSString *age = [animate valueForKey:@"age"];

        NSLog(@"Hello World!");
    }
    return 0;
}
  • 如果将Animate.h和Animate.m中的注释都放开。在NSLog(@"Hello World!");该行打印断点,可以验证出来先执行方法,再执行属性;
  • 验证方法的顺序:先把.h中字段注释,main.m中的字段赋值也进行注释,只留下Animate.m中的几个方法如下:
- (NSString *)getAge
{
    NSLog(@"%@", NSStringFromSelector(_cmd));
    return @"1";
}

- (NSString *)age
{
    NSLog(@"%@", NSStringFromSelector(_cmd));
    return @"2";
}

- (NSString *)isAge
{
    NSLog(@"%@", NSStringFromSelector(_cmd));
    return @"3";
}

- (NSString *)_getAge
{
    NSLog(@"%@", NSStringFromSelector(_cmd));
    return @"4";
}

- (NSString *)_age
{
    NSLog(@"%@", NSStringFromSelector(_cmd));
    return @"5";
}

+ (BOOL)accessInstanceVariablesDirectly
{
    return YES;
}

运行后,发现只打印getAge, 接着注释getAge方法,发现打印的其他方法。依次重复几次,就能得出一个顺序:getKey、key、isKey、_getKey、_key

  • 验证公有字段的执行顺序:通过断点查看给哪个字段进行了赋值。然后注释该字段,依次操作,就可得到执行的顺序:_key、_isKey、key、isKey
  • accessInstanceVariablesDirectly方法默认是返回YES,从方法名称也可以看出来该方法的含义,它用来控制实例变量是否可以访问。

3. KVC中set调用顺序

同样再来一张图,说明执行的顺序,接着验证


图3.1 setValue:forKey:

从图3.1中可以发现和图2.1中左边的实例变量的调用顺序是一样的。只是方法调用少了几个。

结论
  • 右边的方法,左边的字段;(先执行方法,再执行字段)
  • 方法调用顺序:setKey、_setKey
  • 字段调用顺序:_key、_isKey、key、isKey
验证

查看文件Plant相关内容
main.m中有如下内容:

int main(int argc, const char * argv[]) {
    @autoreleasepool {
       
        // set
        Plant *plant = [[Plant alloc] init];
        [plant setValue:@"2" forKey:@"age"];
        
        NSLog(@"Hello World!");
    }
    return 0;
}
  • 验证的方法和上述get的操作类似,就会得出上图的结果。这里请自行验证。
    其中Plant.m中的方法如下:
- (void)setAge:(NSString *)age
{
    NSLog(@"%@--%@", NSStringFromSelector(_cmd), age);
}

- (void)_setAge:(NSString *)age
{
    NSLog(@"%@--%@", NSStringFromSelector(_cmd), age);
}

通过验证,就会和图3.1总结的一样。
关于更高深的其他操作这里不再做分析,只对其基本原理进行剖析。


  • 本文相关的demo已放置github.
  • 在阅读中,如果发现文章有不合理的地方,欢迎提出疑问至邮箱:B12050217@163.com.
  • 原创文章,转载请注明:转自:Try_Try_Try
  • OK, game over.
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容

  • KVC KVC定义 KVC(Key-value coding)键值编码,就是指iOS的开发中,可以允许开发者通过K...
    暮年古稀ZC阅读 2,127评论 2 9
  • KVC(Key-valuecoding)键值编码,单看这个名字可能不太好理解。其实翻译一下就很简单了,就是指iOS...
    榕樹頭阅读 691评论 0 2
  • 该文章属于刘小壮原创,转载请注明:刘小壮[https://www.jianshu.com/u/2de707c93d...
    刘小壮阅读 20,864评论 29 115
  • KVC(Key-value coding)键值编码,单看这个名字可能不太好理解。其实翻译一下就很简单了,就是指iO...
    我的梦工厂阅读 889评论 1 8
  • “一定有什么东西是你热爱并且最喜欢去做的,一个未完成的梦想?” “驯服黑夜” ...
    陈如意的幸福生活呀阅读 295评论 0 1