iOS之KVC赋值和取值的过程

Getter

以下是 valueForKey: 方法的默认实现,给定一个 key 作为输入参数,在消息接收者类中操作,执行以下过程。

  • ① 按照 get<Key><key>is<Key>_<key> 顺序查找方法。
    如果找到就调用取值并执行 ⑤,否则执行 ②;

  • ② 查找 countOf<Key>objectIn<Key>AtIndex:<key>AtIndexes: 命名的方法。
    如果找到第一个和后面两个中的至少一个,则创建一个能够响应所有 NSArray 的方法的集合代理对象(类型为 NSKeyValueArray,继承自 NSArray),并返回该对象。否则执行 ③;

    • 代理对象随后将其接收到的任何 NSArray 消息转换为 countOf<Key>objectIn<Key>AtIndex:<Key>AtIndexes: 消息的组合,并将其发送给 KVC 调用方。如果原始对象还实现了一个名为 get<Key>:range: 的可选方法,则代理对象也会在适当时使用该方法。

  • ③ 查找 countOf<Key>enumeratorOf<Key>memberOf<Key>: 命名的方法。
    如果三个方法都找到,则创建一个能够响应所有 NSSet 的方法的集合代理对象(类型为 NSKeyValueSet,继承自 NSSet),并返回该对象。否则执行④;

    • 代理对象随后将其接收到的任何 NSSet 消息转换为 countOf<Key>enumeratorOf<Key>memberOf<Key>: 消息的组合,并将其发送给 KVC 调用方。

  • ④ 查看消息接收者类的 +accessInstanceVariablesDirectly 方法的返回值(默认返回 YES)。如果返回 YES,就按照 _<key>_is<Key><key>is<Key> 顺序查找成员变量。如果找到就直接取值并执行 ⑤,否则执行 ⑥。如果 +accessInstanceVariablesDirectly 方法返回 NO 也执行 ⑥。

  • ⑤ 如果取到的值是一个对象指针,即获取的是对象,则直接将对象返回。

    • 如果取到的值是一个 NSNumber 支持的数据类型,则将其存储在 NSNumber 实例并返回。

    • 如果取到的值不是一个 NSNumber 支持的数据类型,则转换为 NSValue 对象, 然后返回。

  • ⑥ 调用 valueForUndefinedKey: 方法,该方法抛出异常 NSUnknownKeyException,程序 Crash。这是默认实现,我们可以重写该方法对特定 key 做一些特殊处理。

Setter

以下是 setValue:forKey: 方法的默认实现,给定 key 和 value 作为输入参数,尝试将 KVC 调用方 key 的值设置为 value,执行以下过程。

  • ① 按照 set<Key>:_set<Key>: 顺序查找方法。
    如果找到就调用并将 value 传进去(根据需要进行数据类型转换),否则执行 ②。

  • ② 查看消息接收者类的 +accessInstanceVariablesDirectly 方法的返回值(默认返回 YES)。如果返回 YES,就按照 _<key>_is<Key><key>is<Key> 顺序查找成员变量(同 Getter)。如果找到就将 value 赋值给它(根据需要进行数据类型转换),否则执行 ③。如果 +accessInstanceVariablesDirectly 方法返回 NO 也执行 ③。

  • ③ 调用 setValue:forUndefinedKey: 方法,该方法抛出异常 NSUnknownKeyException,程序 Crash。这是默认实现,我们可以重写该方法对特定 key 做一些特殊处理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值