define

KVC (key-value coding) : Allows developers to access or assign values to properties of objects directly through their key names, so that properties of objects can be accessed and modified dynamically at run time rather than at compile time

Methods overview

Find NSKeyValueCoding in the developer’s manual

KVC: A mechanism for indirectly accessing object properties by name or key

  • Accessor methods

  • Set a value method

  • accessInstanceVariablesDirectly

This method returns a Boolean value indicating whether the key-value encoding method should directly access the corresponding instance variable if the accessor method for the attribute cannot be found

  • Property verification

Commonly used method

The key and keyPath

  • Key: a key
    • You can only accept attributes that the current class has, whether they are its own or inherited from its parent
  • KeyPath: indicates the keyPath
    • In addition to accepting the attributes of the current class, it can also accept the attributes of the current class, that is, it can accept the relationship chain

Accessor methods

- (nullable id)valueForKey:(NSString *)key; - (nullable id)valueForKeyPath:(NSString *)keyPath; // The value can be keyPathCopy the code

An underlying implementation based on getter values

Set a value method

Low-level implementation based on setter set values

Internal KVC calls willChangeValueForKey: and didChangeValueForKey: while modifying a member variable, triggering KVO

Note ⚠️ : Modifying member variables directly does not trigger KVO because it is purely assignment and does not call setter methods

Property verification

//key
- (BOOL)validateValue:(inout id _Nullable * _Nonnull)ioValue forKey:(NSString *)inKey error:(out NSError **)outError;
//keyPath
- (BOOL)validateValue:(inout id _Nullable * _Nonnull)ioValue forKeyPath:(NSString *)inKeyPath error:(out NSError **)outError;
Copy the code

This method defaults to exploring whether there is such a method in the class

  • If so, this method is called to return
  • If not, return YES

Handle exceptions

There are two common exceptions: an incorrect key is passed in and nil is passed in

  • An incorrect key was passed in

    You can do this by overriding the following two methods,

    - (nullable id)valueForUndefinedKey:(NSString *)key;
    - (void)setValue:(nullable id)value forUndefinedKey:(NSString *)key;
    Copy the code
  • Introduced the nil

    If you accidentally pass in nil, KVC will call setNilValueForKey:, which by default throws an exception, so normally we override this method

    -(void)setNilValueForKey:(NSString *)key{NSLog(@" cannot set %@ to nil",key); }Copy the code

Handling non-objects

  • valueForKey:Always return oneidObject, if the original variable type is a value type or structure, the return value is encapsulated asNSNumberorNSValueObject, these two classes handle anything from numbers and bools to Pointers and structs, which then require the developer to manually convert to the original type
  • SetValue: forKey:: does not automatically encapsulate as an object, value types must be converted manually toNSNumberorNSValueType to pass through

KVC and container

The introduction

  • The attributes of an object can be one-to-one or one-to-many
  • One-to-many properties are either ordered (arrays) or unordered (collections)

KVC and ordered containers

Value method: This method returns a mutable ordered array

//key
- (NSMutableArray *)mutableArrayValueForKey:(NSString *)key;
//keyPath
- (NSMutableArray *)mutableArrayValueForKeyPath:(NSString *)keyPath;
Copy the code

Underlying Implementation Principles

KVC and unordered containers

Value method: Method returns a mutable unordered array

//key
- (NSMutableSet *)mutableSetValueForKey:(NSString *)key;
//keyPath
- (NSMutableSet *)mutableSetValueForKeyPath:(NSString *)keyPath;
Copy the code

The underlying implementation

KVC application scenario

Dynamic value Set this parameter

Model and dictionary conversion

In object call setValuesForKeysWithDictionary: method, can pass in a contains the key, the value of the dictionary in KVC all data can be carried out in accordance with the property names and dictionary of key match, and to give a value to the attribute of the User object assignment

Use KVC to access and modify private variables

KVC essentially operates on a list of methods and looks up instance variables in memory, so we can use this feature to access class private variables

This operation is accessible to readOnly properties and @protected member variables

If you do not want the outside world to access a member variable of a class, you can change theaccessInstanceVariablesDirectlyProperty is assigned toNO

Modify the internal properties of some controls


Reference blog:

IOS KVC process details

Basic principles and application scenarios of iOS KVC