Introduction to KVC and KVO in iOS development

Source: Internet
Author: User

In iOS development, KVC and KVO are often used. You can use KVC to assign values to an object's properties and get the object's property values, and you can use KVO to listen for changes in the object's property values. A brief introduction to KVC and KVO.

One: Key value encoding (KVC)

KVC, full name key value Coding (key code), is a feature of the OC Language, which uses KVC to dynamically read and write the properties of an object.

The KVC method is provided by the Nskeyvaluecoding protocol, and NSObject has implemented the protocol, so that almost all objects in OC can use KVC operations. Common methods of KVC operation are:

(1) Setting property values

Setvalue:value Forkey:key (for simple paths, i.e. direct attributes)

Setvalue:value Forkeypath:key (for complex paths, i.e. indirect properties)

(2) Get property values

Valueforkey:key (property value for getting a simple path)

Valueforkeypath:key (used to get property values for complex paths)

Use the code to see the specific uses of KVC:

Two classes are the dog class and the person class, respectively.

Dog.h

1 #import <foundation/foundation.h>2 3 @interface dog:nsobject4 5 @property (nonatomic, copy) NSString *name;6 7 @ End

Dog.m

1 #import "Dog.h" 2 3 @implementation Dog4 5 @end

Person.h

1 #import <Foundation/Foundation.h> 2  3 @class Dog; 4  5 @interface person:nsobject 6  7 @property (Nona Tomic, copy) NSString *name; 8 @property (nonatomic, copy) NSString *sex; 9 @property (nonatomic, strong) Dog *dog;11 @end

Person.m

1 #import "Person.h" 2 3 @implementation Person4 5 @end

Use of KVC:

1 person *person = [[Person alloc] init]; 2     //KVC  setting value 3     [person setvalue:@ "Jim" forkey:@ "name"]; 4     [Person setvalue:@ ' boy ' forkey:@ ' sex ']; 5      6     //KVC Gets the value 7     NSLog (@ "name =%@  sex =%@", [Person valueforkey:@ "name"],[person valueforkey:@ "Sex"]); 8      9     Dog *dog = [[Dog alloc] init];10     person.dog = dog;11     //kvc  set Complex path value     [person setvalue:@ ' Teddy ' forkeypath:@ "Dog.name"];13     //kvc  get complex path values     of NSLog (@ "Dog name =%@", [person valueforkeypath:@] Dog.name "]);

As you can see, KVC uses the corresponding function to set the value and get the value. So, how does KVC find a property to read? KVC follows the following rules, assuming that you want to read the Name property:

(1) Setting Properties: SetName method is preferred, if not, the member variable _name is searched, if not found, the member variable name is searched, and if not found, the Setvalue:forundefinekey: method is called.

(2) Read attribute: GetName method is preferred, if not, the member variable _name is searched, if not found, the member variable name is searched, and if not found, the Valueforundefinekey: method is called.

Second: The use of KVC in Setvaluesforkeyswithdictionary:

There is a very important method in KVC: Setvaluesforkeyswithdictionary:dict, which can map a dictionary to an object, eliminating the need to assign a value to object one by one.

An example of using setvaluesforkeyswithdictionary:dict:

Student.h

1 #import <Foundation/Foundation.h> 2  3 @interface student:nsobject 4  5/** 6  *  Study No. 7  */8 @pro Perty (nonatomic, copy) NSString *num; 9/**10  *  name  */12 @property (nonatomic, copy) nsstring *name;13/**14  *  height  */16 @ Property (nonatomic, assign) float height;17/**19  *  two ways to initialize  *21  */22-(instancetype) Initwithdict: (nsdictionary *) dict;23 + (Instancetype) stuwithdict: (nsdictionary *) dict;24 @end

Student.m

1-(Instancetype) Initwithdict: (Nsdictionary *) dict{2     if (self = [super init]) {3         [self SETVALUESFORKEYSWITHDICTIONARY:DICT]; 4     } 5     return self; 6} 7  8 + (Instancetype) stuwithdict: (Nsdictionary *) Dict 9 {10     

Initialize an object with a dictionary

1-(void) Initstudent 2 {3     nsdictionary *dict = [nsdictionary dictionarywithobjectsandkeys:4     @ "Tom", @ "name", 5< c10/>@ "", @ "num", 6     @ "170.0", @ "height", 7     Nil], 8     Student *stu = [[Student alloc] initwithdict:dict]; 9     NSLog (@ "name =%@ num =%@ height =%f", stu.name,stu.num,stu.height); 10}

The principle of setvaluesforkeywithdictionary:dict

In fact, the Setvaluesforkeywithdictionary:dict method is to traverse Dict and Invoke Setvalue:forkey: method for each key value in Dict. You can simulate setvaluesforkeywithdictionary:dict in the following ways:

1-(void) SetProperty: (Nsdictionary *) dict2 {3 for     (NSString *key in [Dict AllKeys]) 4     {5         nsstring *value = [di CT objectforkey:key];6         [self setvalue:value forkey:key];7     }8}

When called:

1-(Instancetype) Initwithdict: (nsdictionary *) dict{2     if (self = [super init]) {3         //[self Setvaluesforkeyswithdictionary:dict];4         [self setproperty:dict];5     }6     return self;7}

And the Setvaluesforkeywithdictionary:dict function is the same.

Use Setvaluesforkeywithdictionary:dict a place to be aware of

A crash occurs when there is a value in the dictionary, and the object does not have a corresponding property. For example, the new dictionary is as follows:

1-(void) Initstudent 2 {3     nsdictionary *dict = [nsdictionary dictionarywithobjectsandkeys:4     @ "Tom", @ "name", 5< c3/>@ "", @ "num", 6     @ "170.0", @ "height", 7     @ "boy" @ "Sex", nil]; 8     Student *stu = [[Student alloc] INITWITHDICT:DICT]; 9     NSLog (@ "name =%@ num =%@ height =%f", stu.name,stu.num,stu.height); 10}

There is a sex attribute in the dictionary, but there is no property in the Studeng object, and a crash occurs. Workaround:

Implement the Setvalue:forundefinekey: method to handle cases where no attributes are present in the method.

Add code in Student.h:

1-(void) SetValue: (ID) value Forundefinedkey: (NSString *) key;

Add code in STUDENT.M:

1-(void) SetValue: (ID) value Forundefinedkey: (NSString *) Key2 {3     4}

When there are no attributes, the Setvalue:forundefinekey: method is called. Because this method has not been processed, this situation does not handle and does not crash. Note that: Setvalue:forundefinekey: The method is widely used, for example, a key value in a dictionary is an ID, but in OC the ID is a keyword, which can also be handled in the Setvalue:forundefinekey: method.

Three: Key-value monitoring (KVO)

KVO Full name Key Value observing. The KVO can be used to separate the view component from the data model, and the view acts as a listener, and the listener can do the corresponding processing when the model's property values change. The Kvo method is provided by the Nskeyvalueobserving protocol, and the same nsobject already implements the protocol, so that almost all objects can use KVO.

Common ways to use KVO operations are as follows:

Register the Listener for the path: AddObserver:forKeyPath:option:context:

To delete the listener that made the path: Removeobserver:forkeypath:

How to trigger the listener: ObserveValueForKeyPath:ofObject:change:context:

An example of a kvo:

There are two classes: the Dog class and the People class

Dog.h

1 #import <foundation/foundation.h>2 3 @interface dog:nsobject4 5 @property (nonatomic, copy) NSString *name;6 7 @ End

Dog.m

1 #import "Dog.h" 2 3 @implementation Dog4 5 @end

People.h

1 #import <Foundation/Foundation.h> 2  3 @class Dog; 4  5 @interface people:nsobject 6  7 @property (Nona Tomic, copy) NSString *name; 8 @property (nonatomic, strong) Dog *dog; 9 @end

People.m

1 #import "People.h" 2 #import "Dog.h" 3  4 @implementation people 5  6/** 7  *  increased monitoring of DOG during initialization 8  * 9  */10-(void) Setdog: (Dog *) dog11 {     _dog = dog;13     [self.dog addobserver:self forkeypath:@ ' name ' options: Nskeyvalueobservingoptionnew context:nil];14}15/**16  *  override Observevalueforkeypath Method  */18-(void) Observevalueforkeypath: (NSString *) KeyPath Ofobject: (ID) object change: (nsdictionary<nsstring *,id> *) Change Context: (void *) context19 {     if ([KeyPath isequaltostring:@ "name"]) {         NSLog (@ "newName =%@", [Change objectforkey:@ "new"]);     }23}24-(void) dealloc26 {     //Remove listener     [Self.dog removeobserver:self forkeypath:@ "Name"];29}30 @end

To test the KVO function:

1-(void) Testkvo 2 {3     people *people = [[People alloc] init]; 4     people.name = @ "Tom"; 5     dog *dog = [[Dog all] OC] init]; 6     Dog.name = @ "Teddy"; 7     people.dog = Dog; 8      9     //After performing this step, the function that will trigger the listener (Observevalueforkeypath)     Dog.name = @ "Testchange"; 11}

In code, when you modify the Name property of the dog, the listener is triggered, which is

Observevalueforkeypath: (NSString *) KeyPath Ofobject: (ID) object change: (nsdictionary<nsstring *,id> *) Change Context: (void *) the context method.

Introduction to KVC and KVO in iOS development

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.