Introduction:
In the previous article, we talked about KVC. In this article, we learned KVO. The full name is: Key Value Observing. the literal translation is: Key Value-based observer.
So what is its use? KVO is mainly used for view interaction. For example, if some data on the interface changes and the display of the interface also changes, it is necessary to establish a correlation between data and the interface.
KVO provided in ObjC solves this problem. The following example shows how to use KVO by observing the change of course name on the displayed page.
The Student class is named Student and the page class is PageView.
From the official website of Apple: BankObject in the figure is like PageView, while PersonObject is like Student,
PageView observe the changes of Student.
1. Add Student class.
. H
#import <Foundation/Foundation.h>@interface Student : NSObject{ NSString *name; NSString *courseName;}-(void)changeCourseName:(NSString*) newCourseName;@end
The class includes name and Course name courseName. Add a changeCourseName method that can change the course name. For comparison later, check whether there will be a callback when the course name is changed directly.
Implementation file. m
#import "Student.h"@implementation Student-(void)changeCourseName:(NSString*) newCourseName{ courseName = newCourseName;}@end
The implementation class implements the method.
2. Page class implementation
. H file
#import <Foundation/Foundation.h>@class Student;@interface PageView : NSObject{ Student *student;}-(id)init:(Student*)initStudent;@end
. M file
# Import "PageView. h "# import" Student. h "@ implementation PageView-(id) init :( Student *) initStudent {if (self = [super init]) {student = initStudent; [student addObserver: self forKeyPath: @ "courseName" options: Alert | NSKeyValueObservingOptionNew context: nil];} return self;}-(void) dealloc {[student removeObserver: self forKeyPath: @ "courseName" context: nil]; [super dealloc];}-(void) observeValueForKeyPath :( NSString *) keyPath ofObject :( id) object change :( NSDictionary *) change context :( void *) context {if ([keyPath isEqual: @ "courseName"]) {NSLog (@ "PageView course changed"); NSLog (@ "PageView new course is: % @ old Course: % @ ", [change objectForKey: @" new "], [change objectForKey: @" old "]); }}@ end
When init is initialized, add the observer to the student instance and remove the observer when it is released.
3. Observation
In the main function
# Import "Student. h "# import" Course. h "# import" PageView. h "int main (int argc, const char * argv []) {@ autoreleasepool {Student * student = [[Student alloc] init] autorelease]; [student changeCourseName: @ "Mathematics"]; NSLog (@ "Initial Value: % @", [student valueForKey: @ "courseName"]); // create a page instance PageView * pageview = [[[PageView alloc] init: student] autorelease]; [student setValue: @ "Chemistry Course" forKey: @ "courseName"];} return 0 ;}
Create a student instance, set the course to a mathematics class, and initialize it with student when creating the page class. This is a page class that has been observed by students.
Set a new value for the course to chemistry. Run the following command to print the result:
16:29:21. 561 objectiveC [2192: 403]Initial Value:Mathematics
16:29:21. 565 objectiveC [2192: 403] PageViewCourse changed
16:29:21. 566 objectiveC [2192: 403] PageViewNew course is:Chemistry Course Old Course is:Mathematics
You can see that the callback in the Pageview class is called, and Pageview receives the student course data update information.
4. directly change the course information comparison
# Import "Student. h "# import" Course. h "# import" PageView. h "int main (int argc, const char * argv []) {@ autoreleasepool {Student * student = [[Student alloc] init] autorelease]; [student changeCourseName: @ "Mathematics"]; NSLog (@ "Initial Value: % @", [student valueForKey: @ "courseName"]); // create a page instance PageView * pageview = [[[PageView alloc] init: student] autorelease]; [student setValue: @ "Chemistry Course" forKey: @ "courseName"]; [student changeCourseName: @ ""]; NSLog (@ "directly changed course: % @", [student valueForKey: @ "courseName"]);} return 0 ;}
Directly call the changeCourseName method to change the course and print the result:
16:32:06. 230 objectiveC [2240: 403]Initial Value:Mathematics
16:32:06. 237 objectiveC [2240: 403] PageViewCourse changed
16:32:06. 238 objectiveC [2240: 403] PageViewNew course is:Chemistry Course Old Course is:Mathematics
16:32:06. 239 objectiveC [2240: 403]Directly changed the course:English class
We can see that the callback of Pageview is not called. It indicates that the method registered by the observer will be called back only when the value is changed through key-value encoding (KVC.
Here is the KVO documentation on the official website of Apple. If you are good at English, you can see:
Https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/KeyValueObserving/KeyValueObserving.html#//apple_ref/doc/uid/10000177-BCICJDHA