IOS Development — the realization principle and application of KVO

This paper is divided into 2 parts: concept and application. The concept of
part is to analysis the KVO implementation principle of this design pattern;
application by creating a project that KVO resulted in the development of iOS;
is as if just contact KVO beginners can understand the first part of the basic principle of rough look at the underlying implementation principle, then carefully read the application content “second part learn” how to use KVO, then slowly back to deeply understand the implementation of the principle of KVO this “black magic” technology.
[this development environment: Xcode:7.2 iOS By: ah left;
Demo download link: KVO demo Demo]

Conceptual part

What is KVO?

KVO is an implementation of Objective-C for observer design pattern. [another: notification mechanism (notification), details of reference: iOS on design patterns: Notice];
KVO provides a mechanism to specify an observed object (e.g. a class), when the object is an attribute (e.g. A string name) occurred change, the object will be notified. And make the corresponding treatment; [and do not need to add any additional code to the observed objects, we can use the KVO mechanism]

In the MVC design framework of the project, the KVO mechanism is very suitable for the communication between the mode model and the view view. For example:
code, create the attribute data in the model class A, create observation in the controller, once the attribute data change received observer received notification, then use the callback method in the controller processing to achieve B view is updated by KVO; (this should be used are examples of this.)

Two, the realization of the principle?

KVO Apple in the API document is as follows:

Automatic key-value is implemented a technique called observing using isa-swizzling... When an observer registered for attribute an object isa pointer the observed object is modified, pointing to intermediate class rather than at the an true class is of the an of...

The implementation of KVO depends on the powerful Objective-C Runtime, from the above Apple document we can see that apple is written for the realization of the KVO mechanism, and the specific details are not too much, but we can use the method provided by Runtime to explore a few small examples can refer to: [] Runtime, on the bottom the realization principle of KVO mechanism. To this end, left some of the information on the Internet from the KVO summary of the relevant content:

Basic principle:

When observing an object A, the KVO mechanism dynamically creates an object A subclass of the current class and overrides the setter method of the observed property keyPath for this new subclass. The setter method is then responsible for notifying changes in the properties of the observed object.

In-depth analysis:

Apple uses isa to write (isa-swizzling) to achieve KVO. When the observation object A, KVO created a new dynamic mechanism called: new class NSKVONotifying_A, the class inherits from the A object, and the KVO NSKVONotifying_A rewrite observation setter method attribute, the setter method will be responsible before calling the original setter method and then informed of changes of all observed object attributes the value of the.
(Note: isa a (isa-swizzling) isa:is kind of; swizzling: mix, stir;

Analysis of NSKVONotifying_ class A: in this process, the ISA object pointer from the point of the original class A is observed by KVO mechanism is modified to point to the newly created system to achieve a subclass of NSKVONotifying_, the class attribute value change monitoring;
so when we look from the application level, completely unaware of the new class this is the system, “hide” the bottom of the KVO implementation process, let us imagine or the original class. But if we create a new class called “NSKVONotifying_A” (), the program would crash will find that code system to register the KVO, because the system when the dynamic registered listener created the name of NSKVONotifying_A in the middle class, the middle class and point.
(ISA pointer function: each object has a isa pointer, pointing to the object of the class, it tells the Runtime system is the object of the class is what. So when the object is registered as an observer, the ISA pointer points to a new subclass, and the object being viewed magically becomes an object (or instance) of the new subclass Therefore, the call to setter on this object will invoke the overridden setter to activate the key notification mechanism.
– > I guess, this is also the KVO callback mechanism, why are commonly known as one of the reasons for the KVO technology for the dark magic: internal mystery, concise appearance. Analysis of the
subclass setter method: KVO KVO notice two methods rely on NSObject: willChangeValueForKey: and didChangevlueForKey:, respectively before and after the access to call the 2 numerical methods:
observed properties change before willChangeValueForKey: is called, the value of the keyPath attribute of the notification system will change when the change occurs after didChangeValueForKey:; is called, the value of the keyPath attribute of the notification system has been changed; after that, observeValueForKey:ofObject:change:context: will be called. And the setter method that overrides the observation attribute is injected into the inheritance mode at run time, not compile time. The
KVO is an attribute of the observer for the subclass. The call access method works in the code:

- (void) setName: (NSString *) newName{[self willChangeValueForKey:@ "name"]; //KVO before calling the setValue:newName forKey:@ total access method call [super "name"]; / / access method call the parent class [self didChangeValueForKey:@ "name"]; //KVO after calling access method call}

Three, characteristics:

The observer looks at the property, and the KVO callback method is executed only if the value of the KVO property is followed, such as whether the setter method is executed, or whether the KVC assignment is used. If no
assignment by setter or KVC, but directly modify the properties of the corresponding member variables, for example: just call the _name @ = “newName”, this is not the trigger mechanism of KVO, the more does not invoke the callback method.
so the premise of using the KVO mechanism is to follow the KVO property settings to change the value of the property.

Four, step

  • 1 registered observers, the implementation of monitoring;
  • 2 handle changes in attributes in callback methods;
  • 3 remove observer

Application part

Five. Implementation method (apple API document method):

A. registered observer:

The first parameter: observer / / observer (here to observe attribute change self.myKVO object) / second keyPath parameters: the attribute name is observed (here to observe the value of the num attribute in the self.myKVO change) / / third options parameters: To observe the nature of the value, the old value (some configuration enumeration value according to the needs of for example, here you can use two / fourth parameters: Context) context, can the callback method the value (for example, KVO is set to a place data dictionary) [self.myKVO addObserver:self forKeyPath:@ options: NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:nil] "num";

When the value of the B. property (keyPath) changes, the notification is received, and the following methods are called:

The object //change: change //keyPath: property name //object: was observed before and after the register values are stored in the change dictionary //context: observer, context Chuan - (void) observeValueForKeyPath: (NSString *) keyPath ofObject: (ID) object (change: NSDictionary< NSString id> * *, change) context: (void * context) {}

Six, the code:

1 new projects

The following UI interface design:
is the first note, used to display num and ViewController numerical Association named: label
; second is the button, for varying the value of num, ViewController and named as changeNum.

IOS Development -- the realization principle and application of KVO

2 model creation

Create a new File, select Cocoa Touch Class, named “myKVO”, remember to choose Subclass of “NSObject”:

(myKVO.h):

@interface myKVO: NSObject @property (nonatomic, assign) int num; / / attribute to int type of [email protected]

(myKVO.m):

#import "myKVO.h" @implementation @synthesize num; @end; myKVO

3 monitor and respond to changes in attributes in ViewController.

(ViewController.h):

#import < UIKit/UIKit.h> @interface; ViewController: UIViewController @property (weak, nonatomic) IBOutlet UILabel *label; / / Note - label (IBAction) changeNum: (UIButton * sender); / / @end button event

(ViewController.m):

#import "ViewController.h" #import "myKVO.h" @interface (ViewController) @property (nonatomic, strong) myKVO *myKVO; @end @implementation ViewController (void viewDidLoad) {[super viewDidLoad] = [[myKVO; self.myKVO alloc]init]; /*1. myKVO as the registered object observed: option, NSKeyValueObservingOptionOld provides the initial object data in the form of a dictionary; NSKeyValueObservingOptionNew "data" new updates to the dictionary form; * / [self.myKVO addObserver:self forKeyPath:@ "num" options: NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:nil];} / * 2 as long as the keyPath object attribute changes, will call this callback method for the corresponding treatment: UI update: * / - (void) observeValueForKeyPath: (NSString * keyPa) Th ofObject: (ID) object (change: NSDictionary< NSString id> change * *) context: (* void) / / context{to determine whether the self.myKVO attribute "num": if ([keyPath isEqualToString:@ num & & object = = self.myKVO) {/ / response changes: UI update (label text change self.label.text = [NSString stringWithFormat:@) "the current num value:% @" "new" [change, valueForKey:@ "; //change: using the above registration, enumeration is 2, so this method can extract the NSLog of two old and new values in the change Dictionary (@" //noldnum:%@ newnum:%@ "," [change valueForKey:@ old "" [change valueForKey:@ "new"]);}} and /*KVO notice of cancellation, in general - (void) dealloc in the preparation of. As many small partners asked why in didReceiveMemoryWarning? Because this example is seen in the book, so try to use it as an example. But Xiao Bian is still recommended to put off the act - (void) dealloc. (serious face) * / - (void) didReceiveMemoryWarning {[super didReceiveMemoryWarning]; / * * / [self removeObserver:self forKeyPath:@ KVO 3 to remove "num context:nil]";} / / button event - (IBAction) changeNum: (UIButton * sender) {/ / at a time, so that the value of the num +1 self.myKVO.num = self.myKVO.num + 1}; @end

Note: no debugging label initialization value, when the click of a button, label recorded num increased, indicating that the button to make the property num increased at the same time, KVO sent notification mechanism, and call the observeValueForKeyPath: method to update UI. Demo download link: KVO demo Demo)

Seven, expand –>

1.KVC is different from KVO?

KVC (key encoding), that is, Key-Value Coding, an informal Protocol, the use of string (key) access to an object instance variable mechanism. Rather than by calling the Setter, Getter methods, such as explicit access to access.
KVO (Key-Value Observing, key monitoring), it provides a mechanism to attribute when the specified object is modified, the object will receive notification, the premise is the implementation of the setter method, or the use of the KVC assignment.

The difference between 2 and notification (notice)?

Notification more than KVO to send a notification step.
both are one to many, but the direct interaction between the objects, notification is much more obvious, the need for notificationCenter as the middle interaction. But as we introduce KVO, set the observer -> processing attribute change for intermediate notification of this loop, secret more, leaving only one sentence “by the system notice”, can refer to the above analysis of the specific implementation process.

The advantage of notification is not limited to monitor changes in property, can also monitor the state of diversity, monitoring a wide range, such as the use of the keyboard, such as Taiwan before and after the notice system is more flexible and convenient.
(refer to notification mechanism fifth section system notification name content)

3 different from delegate?

Like delegate, the role of KVO and NSNotification is the communication between classes and classes. But with the delegate difference is:
the two are responsible for sending and receiving notification, the rest of the things by the system, so do not return a value; and the delegate communication object through the variable (agent);
delegate is generally one and the two one to many.

4 involving technology:

KVC/KVO is the realization of the dynamic Objective-C and runtime, as well as the realization of accessor methods;

Summary:

Compared with other callback method to realize the use of the KVO mechanism, more supported by the system, compared with notification, delegate and other more concise, and can provide the latest observation of attribute values and original values; but the corresponding in the subclass, rewriting method etc. the memory consumption is very great. So for the communication between the two classes, we can according to the actual development of the environment using different methods, making the development of the project more concise and practical.

also need to pay attention, this is due to the injection of inheritance in run time rather than at compile time, if the given instance is not observed, then the KVO will not have any overhead, because at this time there is no existing KVO code. But even without the observer, the Commission and the NSNotification still have to work, which is also the advantage of KVO’s zero cost observation here.


(reprint please indicate the source, thank you ~ ~ ^ – ^)
by: ah ~ left