KVC key value encoding is a mechanism enabled by the NSKeyValueCoding informal protocol. Objects use protocols to access object properties indirectly.

1. Use the key to set the value or value

  • setValue: forfey:
  • setValue: forKeyPath:

2. Set the value to keyPath

  • valueForKey:
  • valueForKeyPath:

The underlying implementation

The setKey: value: set value

  1. Check for setKey,_setKey, and _setIsKey. Key is a member variable
  2. If these three key is not found, is to find whether accessInstanceVariablesDirectly returns YES (the default returns YES), if YES, will search for direct access to the instance variable assignment, Search for members in _key,_iskey,key,iskey order
  3. If not found or accessInstanceVariablesDirectly return NO, indicate a setter method and instance variables are not found, the system will perform setValue: forUndefinedKey: Method, which throws an NSUndefinedKeyException type exception if it is not implemented

Value valueForKey:

  1. First look for getter methods in the order of getKey and key. If found, perform step 5. Otherwise, perform Step 2
  2. Look for countOfKey, objectInKeyAtIndex, and keyAtIndexes
  • If either countOfKey or the other two methods are found, a proxy object for the collection of methods that responds to all NSArray is created and returned, NSKeyValueArray, which is a subclass of NSArray.
  • The proxy object then converts all the naraary messages it receives to countOfKey, objectInKeyAtIndex, and keyAtIndexes: some combination of messages used to create key-encoded objects.
  • If the original object also implements an optional method called getKey: range:, then the proxy object will use that method as appropriate (note: method names are named according to KVC’s standard naming conventions, including method signatures). If not, go to part 3:
  1. None of the above methods were found
  • The countOfKey, enumeratorOfKey, and memberOfKey methods are all searched.
  • If all three methods are found, a collection proxy object that responds to all NSSet methods is created and returned. This proxy object then converts all NSSet messages it receives into some combination of countOfKey enumeratorOfKey memberOfKey messages, Object used to create it.
  • If not, go to step 4.
  1. Check whether accessInstanceVariablesDirectly class method to YES, if YES, find a member variable _key, _iskey, key, iskey, if found the key into the step 5, If not found or accessInstanceVariablesDirectly entering a step 6 to NO
  2. Returns different results depending on the attribute value type found, or directly if it is a pointer type; If it is a standard type supported by NSNumebr, it is stored in the NSNumebr instance and the value is returned; If neither, it is cast to NSValue and returns.
  3. If no corresponding key is found, the valueForUndefinedKey method is executed. If the method is not implemented, an exception of type NSUndefinedKeyException is thrown.

Custom KVC assignment

The idea behind custom set methods:

1. Check whether the key value exists. If the key value does not exist, return directly.

2. Search for setter methods: setKey, _setKey, and setIsKey.

3. Determine whether accessInstanceVariablesDirectly to YES for YES to continue with the following process, to NO exception is thrown directly.

4. Assign values to indirectly accessed variables (only once) in _Key, _isKey, Key, and isKey order.

  • Defines a mutable array that collects instance variables
  • Get the ivAR by class_getInstanceVariable
  • Object_setIvar assigns the corresponding IVar
  1. If the associated instance variable cannot be found, an exception is thrown

The idea of customizing get methods:

1. Check the key.

2. Search for the corresponding methods in the following order: getKey, Key, countOfKey, objectInKeyAtIndex (Key is the Key value passed in).

3. Determine whether accessInstanceVariablesDirectly to YES (whether direct assignment instance variables, YES is ok). NO throws an exception. (Throwing an exception is a crash).

4. Indirectly access instance variables in _Key, _isKey, Key, and isKey order

  • Defines a mutable array that collects instance variables
  • Run class_getInstanceVariable to obtain the ivAR
  • Object_getIvar returns the corresponding IVAR value