Object-C-KVO & amp; oc notification, object-ckvo

Source: Internet
Author: User
Tags notification center

Object-C-KVO & oc notification, object-ckvo

KVO is a key-value-encoding-based technique.

Key-value observation can be used to register as an object's observer and receive a notification when a property of the object changes.

To write an access method that complies with the KVC standard for the observed object, write the key-value observation in the following three steps:

(1) register as an observer.

(2) define the KVO callback.

(3) Remove the observer.

+ Create a class Student with the attribute name and age.

@interface Student : NSObject@property(copy,nonatomic) NSString * name;@property(nonatomic) int age;@end

Create a Parent class as the observer. Main function:

Student * student = [Student new]; Parent * parent = [Parent new]; // establishes the observer mode relationship and registers the observer [student addObserver: parent forKeyPath: @ "name" options: NSKeyValueObservingOptionNew | Using context: nil]; [student addObserver: parent forKeyPath: @ "age" options: NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context: nil];

The first parameter: (student) is observed.

Second parameter: (parent) Observer.

Third parameter: (forKeyPath) Key Path parameter, the Key Path to be observed. Here we observe the name and age.

The fourth parameter: (options) identifies how KVO wants to pass the change to the observer. You can use | for multiple selections. Here, we observe the new and old values of the change.

Fifth parameter: context memory zone, usually nil

+ Define the KVO callback in the parent. m file.

@ Implementation Parent // The Observer implements the key value observation method. to be an observer, You need to implement this method. -(Void) observeValueForKeyPath :( NSString *) keyPath ofObject :( id) object change :( NSDictionary *) change context :( void *) context {id oldValue = [change objectForKey: NSKeyValueChangeOldKey]; id newValue = [change objectForKey: NSKeyValueChangeNewKey]; NSLog (@ "the value of attributes % @ of the parent object: % @ has changed. The old value is % @, new Value: % @ ", object, keyPath, oldValue, newValue );}

Change is a dictionary.

+ If the name or age of student changes (the observer must be removed ):

Student * student = [Student new]; Parent * parent = [Parent new]; // establishes the observer mode relationship and registers the observer [student addObserver: parent forKeyPath: @ "name" options: NSKeyValueObservingOptionNew | inclucontext: nil]; [student addObserver: parent forKeyPath: @ "age" options: Role | NSKeyValueObservingOptionOld context: nil]; student. age = 10; student. name = @ "James"; // before the end, you need to remove the observer [student removeObserver: parent forKeyPath: @ "age"]; [student removeObserver: parent forKeyPath: @ "name"];

The callback defined on the parent is automatically executed and the result is printed:

Of course, you can also observe one object with multiple objects and create a new teacher class. In this way, there are two observers:

Student * student = [Student new]; Parent * parent = [Parent new]; Teacher * teacher = [Teacher new]; // establishes the observer mode relationship and registers the observer [student addObserver: parent forKeyPath: @ "name" options: NSKeyValueObservingOptionNew | encryption context: nil]; [student addObserver: teacher forKeyPath: @ "age" options: Allow | encryption context: nil]; [student addObserver: parent forKeyPath: @ "age" options: NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context: nil]; student. age = 10; student. name = @ "James"; // before the end, you need to remove the observer [student removeObserver: parent forKeyPath: @ "age"]; [student removeObserver: parent forKeyPath: @ "name"]; [student removeObserver: teacher forKeyPath: @ "age"];

 

****************************************

 

Another situation: create a Family class, make student an attribute, and then make the Family an observer of student. In this way, the method for registering the observer can be written in the init method of the Family, remove the observer and write it in the dealloc method of Family:

Family. h file:

@interface Family : NSObject@property(strong,nonatomic) Student * student;-(id) initWithStudent:(Student *)student;@end

Family. m file:

@ Implementation Family-(id) initWithStudent :( Student *) student {if (self = [super init]) {self-> _ student = student; // make the current object the observer of student [self-> _ student addObserver: self forKeyPath: @ "name" options: NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context: nil];} return self ;} // The observer must implement the key value observation method as the observer. -(Void) observeValueForKeyPath :( NSString *) keyPath ofObject :( id) object change :( NSDictionary *) change context :( void *) context {id oldValue = [change objectForKey: NSKeyValueChangeOldKey]; id newValue = [change objectForKey: NSKeyValueChangeNewKey]; NSLog (@ "the value of the property % @ of the home object: % @ has changed; the old value is % @, new Value: % @ ", object, keyPath, oldValue, newValue);}-(void) dealloc {NSLog (@" Family dealloc... "); // remove the observer [self-> _ student removeObserver: self forKeyPath: @" name "]; // ARC so super dealloc does not need to be written} @ end

Main:

    Student * student = [Student new];    Family * family = [[Family alloc]initWithStudent:student];    student.name = @"hehe";

We can see that the KVO mode has a high Coupling Degree and there is a direct relationship between classes. Next, let's look at the notifications.

Custom notifications

Notifications are a design pattern in the iOS development framework. Notifications are generally used for information transmission between M, V, and C. For example, set the page and App skin.

NSNotification

Before using notifications, we need to create notification objects. The Notification object has two important member variables: name and object. Generally, name uniquely identifies a notification object, and object indicates the notification sender.

The Notification object contains a dictionary (an optional parameter) that stores information during value transfer for the recipient. The system requires this parameter to be an unchangeable dictionary.

NSNotificationCenter

After a notification is created, you can send the notification when necessary. When sending the notification, you need a control center to send the notification, which is the notification center.

The notification center is the brain of the notification mechanism architecture. It allows us to register a notification listener, send a notification, and remove a notification listener.

Generally, system notifications do not need to be sent. You only need to register the notification listener and remove the notification listener. For example, whether the video playing is complete.

Chestnut, Teacher sends a notification. Student reception:

Page Structure:

The instructor has a sending method. Teacher. h file:

@interface Teacher : NSObject- (void) sendMessage;@end

Teacher. m file:

# Import "MacroDefinition. h "@ implementation Teacher-(void) sendMessage {NSNotification * myNotification = [NSNotification notifnotifwithname: kMyNotificationName object: self userInfo: @ {@" content ": @" students, Monday off, "}]; // send a notification // use the notification center to send the notification. // The notification center is a singleton mode nsicationicationcenter * center = [NSNotificationCenter defacenter center]; [center postNotification: myNotification];} @ end

The notificationWithName in NSNotification is also used in other places, so the macro definition is written into a separate. h file MacroDefinition, and the file contains: # define kMyNotificationName @ "customNotification ". Userinfo is a dictionary that stores notification content.

First, write the callback method after Student receives the notification:

Student. h file:

@ Interface Student: NSObject // It can be associated with one parameter, but it can only be an NSNotification object. -(Void) receiveMessage :( NSNotification *) notification; @ end

Student. m file:

@ Implementation Student-(void) receiveMessage :( NSNotification *) notification {NSLog (@ "Object % @ sends a notification with the name: % @. The additional data is: % @", notification. object, notification. name, [notification. userInfo objectForKey: @ "content"]);}

Main introduction:

# Import "MacroDefinition. h"
# Import "Teacher. h"
# Import "Student. h"

Teacher * teacher = [Teacher new]; Student * student1 = [Student new]; Student * student2 = [Student new]; Student * student3 = [Student new]; // subscribe to the notification center nsicationicationcenter * center = [NSNotificationCenter defacenter center]; // register. The first parameter is the observer, and the second parameter is the notification that the observer receives, the third parameter is the name of the notification that the observer cares about, and the fourth parameter is the notification object that the observer cares about. [Center addObserver: student1 selector: @ selector (receiveMessage :) name: jsonobject: nil]; [center addObserver: student2 selector: @ selector (receiveMessage :) name: kMyNotificationName object: nil]; [center addObserver: student3 selector: @ selector (receiveMessage :) name: kMyNotificationName object: nil]; // send [teacher sendMessage]; // remove the subscriber in principle [center removeObserver: student1 name: kMyNotificationName object: nil]; [center removeObserver: student2 name: kMyNotificationName object: nil]; [center removeObserver: student3 name: kMyNotificationName object: nil];

Print result:

The notification center is in singleton mode, so kmyicationicationname, main and Teacher. m are the same, so the two files use the same macro definition.

In this way, there is no direct relationship between the two classes, but the message is transmitted through the notification center. For more information about the notification, add =. =

 

Difference between KVO and notification:

1: KVO classes are directly linked with a high Coupling Degree. The notification is not directly linked.

2: as long as the attribute changes, the observer will be responded. The notification is sent by the observer first, and then the observer registers the listener to respond. This is one more step than KVO to send the notification, but the advantage is that the listener is not limited to attribute changes, you can also listen to a variety of status changes for a wide range of listening and more flexible use.

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.