• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

iOS—— KVC

武飞扬头像
zxb10
帮助1

KVC

KVC概念

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

KVC基本API方法

- (nullable id)valueForKey:(NSString *)key;      //直接通过Key来取值

- (void)setValue:(nullable id)value forKey:(NSString *)key; //通过Key来设值

- (nullable id)valueForKeyPath:(NSString *)keyPath;   //通过KeyPath来取值

- (void)setValue:(nullable id)value forKeyPath:(NSString *)keyPath; //通过KeyPath来设值


在这里要注意的是前两种方法是KVC的设值,后两种方法是KVC的取值。

其他方法
// 默认返回YES,表示如果没有找到Set<Key>方法的话,会按照_key,_iskey,key,iskey的顺序搜索成员,设置成NO就不这样搜索
  (BOOL)accessInstanceVariablesDirectly;

// KVC提供属性值正确性验证的API,它可以用来检查set的值是否正确、为不正确的值做一个替换值或者拒绝设置新值并返回错误原因。
- (BOOL)validateValue:(inout id __nullable * __nonnull)ioValue forKey:(NSString *)inKey error:(out NSError **)outError;

// 这是集合操作的API,里面还有一系列这样的API,如果属性是一个NSMutableArray,那么可以用这个方法来返回。
- (NSMutableArray *)mutableArrayValueForKey:(NSString *)key;

// 如果Key不存在,且KVC无法搜索到任何和Key有关的字段或者属性,则会调用这个方法,默认是抛出异常。
- (nullable id)valueForUndefinedKey:(NSString *)key;

// 和上一个方法一样,但这个方法是设值。
- (void)setValue:(nullable id)value forUndefinedKey:(NSString *)key;

// 如果你在SetValue方法时面给Value传nil,则会调用这个方法
- (void)setNilValueForKey:(NSString *)key;

// 使用字典为Model赋值
- (void)setValuesForKeysWithDictionary:(NSDictionary<NSString *, id> *)keyedValues;

// 输入一组key,返回该组key对应的Value,再转成字典返回,用于将Model转到字典。
- (NSDictionary<NSString *, id> *)dictionaryWithValuesForKeys:(NSArray<NSString *> *)keys;


学新通

首先我们来看设值

设值

最简单的是用key方法直接设值:

Person* person = [[Person alloc]init];
 [person setValue:@namevalue forKey:@"name"];


还可以使用keyPath方法进行多重设值

Person* person = [[Person alloc]init];
[person setValue:@1 forKeyPath:@"dog.age"];

id age = [person valueForKeyPath:@"dog.age"];
NSLog(@"%@", age);

Dog类和Person类是两个继承NSObject的类,先在Person类里面设置Dog类型的属性,在Dog类里设置int类型的age属性,即可完成设值过程。

取值

在取值过程中,优先级是最重要的一点,一定要搞清楚KVC取值的优先级,我们可以先来看下图:

学新通
学新通

第一优先级

在这个过程中,第一优先级是getter方法,也就是说在取值的时候,先判断有没有getter方法,如果有的话直接取值成功,不需要后面的步骤了。

- (NSString*)name {
    return @"666";
}
- (NSString*)getName {
    return @"get666";
}
- (NSString*)isName {
    return @"is666";
}

我们在Person的m文件中把三个getter方法全写上,此时打印:

Person* person = [[Person alloc]init];
    NSString* name = [person valueForKey:@"name"];
    NSLog(@"%@", name);

学新通

我们发现在所有getter方法里面,优先级最高的是getName方法,然后我们把这个方法注释掉,经过实验得出结论:

在三个getter方法中,优先级排序:
getKey > key > isKey

第二优先级

我们发现上图中在第二优先级前面有一个方法,这个方法是什么呢,我们来看看:
学新通

  (BOOL)accessInstanceVariablesDirectly

这个方法是BOOL类型,用来判断是否需要查找第二优先级,默认情况下为Yes,如果返回值改为No,就跳过查找第二优先级。

此时我们对成员变量通过重写init方法进行赋值:

- (instancetype)init {
    if (self = [super init]) {
        //成员变量
        _name = @"_name";
        _isName = @"_isName";
        name = @"name";
        isName = @"isName";
    }
    return self;
}

在进行第二级优先级测试的时候,先把第一优先级的方法注释起来,然后运行程序:
学新通

同样用刚才相同的方法进行测试,发现第二级方法的优先级:

_key > _iskey > key > iskey

那么如果两种情况都没有呢?

我们将代码都注释掉来试试:
学新通

这时候程序编译没问题,运行时就会报经典的Undefine问题了。

KVC问题其实是一个比较抽象的问题,如果文章难以理解的话,这里推荐一个视频博主,关于此节内容讲解十分细致:
KVC视频链接

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgcbaah
系列文章
更多 icon
同类精品
更多 icon
继续加载