问题: 讲一下KVC赋值的具体过程.


  1. 外部通过调用 setValue: ForKey: 方法.

  2. 首先先判断是否有属性的Set方法 setKey: 或者 _setKey: ,如果有,则直接调用方法传入参数.

  3. 如果没有 setKey: 或者 _setKey:,则会调用 accessInstanceVariablesDirectly.

  4. 如果 accessInstanceVariablesDirectly 返回值为NO,那么就会调用 setValue:forUndefinedKey: 并且抛出NSUnknowKeyException异常.

  5. 如果 accessInstanceVariablesDirectly 返回值为YES,那么他会按照 _key → _isKey → key → isKey 顺序去查找成员变量.如果查找到则完成赋值,如果查找不到则依然会调用 setValue:forUndefinedKey:,并且抛出 NSUnknowKeyException 异常.

示意图如下所示.


问题: KVC赋值过程会不会触发KVO呢?


KVC的赋值过程会触发KVO.

  • 情景1:(当前类含有该属性) KVC的赋值过程实际上会调用属性的Set方法
  • 情景2:(当前类未含有该属性,但含有成员变量) KVC的赋值过程实际上会手动调用willChangeValueForKey:didChangeValueForKey:.所以仍然会触发KVO.

问题: 讲一下KVC取值的具体过程.


  1. 外部调用 valueForKey: 方法.

  2. 首先查找 getKey:key:isKey:_key 四个方法,如果有则进行调用并且返回其值.

  3. 上述方法未找到,则判断 accessInstanceVariablesDirectly 的返回值,如果为NO,那么直接调用 valueForUndefinedKey: 抛出 NSUnknowKeyException 异常.

  4. 如果 accessInstanceVariablesDirectly 返回值为YES,那么直接 按照 _key_isKeykeyisKey 顺序查找并且赋值.

  5. 如果上述查找不到,那么就仍然调用 valueForUndefinedKey: 并且抛出 NSUnknowKeyException 异常.


IT界无底坑洞栋主 欢迎加Q骚扰:676758285