KVO: (key-value Observer) is a concrete implementation of the Observer design pattern (communication between C layer and M layer).

KVO trigger mechanism: one object (observer) detects whether a property of another object (observed) has changed. If the monitored property has changed, a method of the observer (method name is fixed, similar to proxy method) will be triggered.

Use steps:

  1. Register observer (specifies observer and observed attributes for being observed)
  2. Implement the callback method
  3. Trigger the callback method
  4. Remove observer

Causes of general KVO collapse:

  1. The observed object is destroyed (the observed object is a local variable)
  2. The observer is released, but the listener is not removed (modal push, push,pop, etc.)
  3. The registered listener is not removed, and the listener is registered again

The implementation is as follows: (Here is an observation of the Name property of the Person class.) The person.h file

@interface Person : NSObject @property(nonatomic,strong)NSString *name; - (void)changeName:(NSString*)name; - (void)changeNameFromSetter:(NSString*)name; @endCopy the code

Person. M file

#import "person.h" @implementation name - (void)changeName:(NSString*)name{_name = name; } // second point syntax assignment - (void)changeNameFromSetter:(NSString*)name {self.name = name; } @endCopy the code

RootViewController. M file

#pragma mark - Initialize person - (void)initPerson{self.person = [[person alloc] init]; Self.person. name = @" original name "; } # pragma mark - button method - (void) changeColor {/ / self. The backgroundColor = [UIColor colorWithRed: arc4random () % of 256/255.0 Green: arc4random () % 256/255.0 blue: arc4random () % 256/255.0 alpha: 1); self.view.backgroundColor = [UIColor redColor]; }Copy the code

1. Register observers

//observer observer (observing changes in properties of the self.view object) //KeyPath: names of properties to be viewed //options: // Context: context can pass values to kVO callback methods // here self.view is observed // Register observer (can be multiple) /* options: There are four values, which are: NSKeyValueObservingOptionOld NSKeyValueObservingOptionNew before the change of value for processing method after the change of value for processing method NSKeyValueObservingOptionInitial to initialize values for processing method, once registered, immediately call again. It usually takes the new value, not the old value. NSKeyValueObservingOptionPrior points 2 times call. Before the value changes and after the value changes. */ [self.person addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionOld context:nil];Copy the code

2. Implement the callback method

#pragma mark - kvo callback method (system-provided callback method) //keyPath: property name //object: object to be observed //change: Values before and after changes are stored in the change dictionary - (void) observeForkeypath :(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context { id oldName = [change objectForKey:NSKeyValueChangeOldKey]; NSLog(@"oldName----------%@",oldName); id newName = [change objectForKey:NSKeyValueChangeNewKey]; NSLog(@"newName-----------%@",newName); // [object removeObserver:self forKeyPath:@"name"]; }Copy the code

3. Trigger the callback method (note here, in the person. m file if the assignment is not via setter methods or KVC, for example (_name = KVC callback method will not be triggered. Setter method or KVC callback method will not be triggered.

/ / the left navigation bar self. NavigationItem. LeftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle: @ "underline" style:UIBarButtonItemStylePlain target:self action:@selector(oldAction)]; / / right button navigation self. NavigationItem. RightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle: @ "point of grammar" style:UIBarButtonItemStylePlain target:self action:@selector(newAction)];Copy the code
#pragma mark - Navigation bar button method (if assignment is not via setter method or KVC, such as (_name = @" new value "), this time does not trigger KVC callback method) // Assign by underscore (does not trigger callback method) - (void)oldAction {self.person changeName:@" changeName "]; } // Assign by point syntax - (void)newAction {[self.person changeNameFromSetter:@" li4 "]; }Copy the code

4. There are two ways to remove the observer: First, when the interface is about to disappear, remove KVO

// Remove kVO [object removeObserver:self forKeyPath:@"name"] when the interface disappears;Copy the code
- (void)dealloc { 
    [self.person removeObserver:self forKeyPath:@"name"]; 
    self.person = nil; 
}
Copy the code

The above is the basic use of iOS KVO details, I hope to help you

The original address