KVO

KVO stands for key-value Observing, which is used to monitor the change of object attribute values

The use of the KVO
  1. Adds KVO to an object property
[p addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
Copy the code
  1. Implement KVO methods to listen for changes in property values
/** keyPath: key object of the property to be viewed change: object for changing the property context: context */
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
    NSLog(@" I heard a change in the %@ property of %@", object, keyPath);
    NSLog(@ "% @", change);
}
Copy the code
The principle of KVO
  1. At the bottom of iOS, isa-Swizzling is implemented. When we add KVO to object A, we dynamically create A class named NSKVONotifying_A that inherits from A’s own class.
  2. The ISA pointer to object A points from class A to NSKVONotifying_A, and the superclass pointer to NSKVONotifying_A points to class A.
  3. Override setter methods in NSKVONotifying_A and do some KVO related processing in them
  4. When we modify the property of A object, we will find the list of methods in class NSKVONotifying_A through isa pointer, and execute the setter method overridden by NSKVONotifying_A to implement KVO processing

We can make this clear by printing the ISA pointer

How does KVO override setter methods

Through the above analysis, we can guess that the setter method rewritten by KVO may be:

- (void)setName:(NSString *)name {
    [self willChangeValueForKey:@"name"];
    // Change the value of name
    [self didChangeValueForKey:@"name"]; // Trigger observeValueForKeyPath: method, callback to observer
}
Copy the code

KVC

KVC stands for key-value Coding, which allows access to an attribute of an object through the string Key

The use of KVC

Common KVCAPI are:

- (void)setValue:(id)value forKeyPath:(NSString *)keyPath;
- (void)setValue:(id)value forKey:(NSString *)key;
- (id)valueForKeyPath:(NSString *)keyPath;
- (id)valueForKey:(NSString *)key; 
Copy the code
SetValue :forKey: search process
  1. Find by key: setKey, _setKey method, call setter method
  2. Check accessInstanceVariablesDirectly function return values, if is NO, step 4. (the default is YES)
  3. Find the member variables of _key, _isKey, key, and isKey and assign them
  4. Call the setValue: forUndefinedKey: and throw an exception NSUnknownKeyException
ValueForKey: Search process
  1. Find the getKey, key, isKey, _key methods and call the getter method
  2. AccessInstanceVariablesDirectly function return values, if it’s NO, step 4. (the default is YES)
  3. Find the member variables of _key, _isKey, key, and isKey
  4. Call valueForUndefinedKey: and throw an NSUnknownKeyException

KVC with KVO

  1. KVO can be triggered by assigning a value to a property directly, but can it be triggered by KVC? can

  1. Can KVO be triggered by assigning a value directly to a member variable of an object? Can not be