[Objective-c] 021 KVC, KVO

Source: Internet
Author: User



C # has written that C # is particularly handy for reading and writing the properties of an object through reflection, and can be used to dynamically control an object in the form of a string. In fact, in the OBJC, we can be more advanced point, do not have to do anything to dynamically read and write properties, this way is the key Value Coding (abbreviation KVC).



KVC (key value encoding)

The operation method of KVC is provided by the Nskeyvaluecoding protocol, and NSObject implements this protocol, that is to say, almost all the objects in OBJC support KVC operation, the common KVC operation method is as follows:


    1. Dynamic settings: SetValue: Property value Forkey: Property name (for simple Path), SetValue: Property value Forkeypath: Property path (for compound path, for example, person has an account type property, Then Person.account is a composite property)
    2. Dynamic read: Valueforkey: Property name, Valueforkeypath: property name (for compound path)


Let's illustrate with a simple example



Blog class


//////////////////////// Blog.h ////////////////////
#import <Foundation/Foundation.h>

@interface Blog: NSObject

//Number of articles
@property(nonatomic,assign)int essayCount;
@end

/////////////////////// Blog.m ///////////////////
#import "Blog.h"

@implementation Blog

@end 


User class


 
////////////////////// User.h /////////////////////
#import <Foundation/Foundation.h>
#import "Blog.h"

@interface User : NSObject

@property(nonatomic,copy)NSString *name;
@property(nonatomic,assign)int age;
@property(nonatomic,retain)Blog *blog;

- (void)showUserInfo;
@end

//////////////////// User.m /////////////////////
#import "User.h"

@implementation User

- (void)showUserInfo {
    NSLog(@"userName=%@,userAge=%d,essayCount=%d",_name,_age,_blog.essayCount);
}

@end


Main


 
#import <Foundation/Foundation.h>
#import "Blog.h"
#import "User.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
        User *newUser = [[User alloc] init];
        [newUser setValue:@"zhangsan" forKey:@"name"];
        [newUser setValue:@"18" forKey:@"age"];
        [newUser showUserInfo];
        
        Blog *newBlog = [[Blog alloc] init];
        [newUser setValue:newBlog forKey:@"blog"];
        [newUser setValue:@"100" forKeyPath:@"blog.essayCount"];
        [newUser showUserInfo];
    }
    return 0;
}


Test results:



2016-01-10 23:29:17.809 kvc_kvo[45598:582500] username= Zhang San, userage=18,essaycount=0
2016-01-10 23:29:17.810 kvc_kvo[45598:582500] username= Zhang San, userage=18,essaycount=100
Program ended with exit code:0



In the example above, KVC is relatively simple to use, but how does it read and set a property? (Suppose you want to use KVC to read the name now)


    1. To set properties dynamically: The SetName method is preferred, and if not, the search member variable _name, if it does not exist, the search member variable name, or the SetValue of the class if it is still not searched: Forundefinedkey: Method (Note that the search process, regardless of whether these methods, the member variables are private or public can be set correctly);
    2. Dynamic Read properties: The call to the name method (the getter method of property a) is preferred, and if no search is reached then the member variable _name is first searched, if it still does not exist then the search member variable name, The valueforundefinedkey of this class will be called if there is still no search: method (Note that the search process is read correctly regardless of whether the method, the member variable is private or public);


KVO (Key-value monitoring)



KVO is an observer pattern that makes it easy to separate the view component from the data model, and when the data model's property values change, the view component as the listener is fired, and the listener itself is invoked when fired. To implement KVO in OBJC, the Nskeyvalueobserving protocol must be implemented, but fortunately NSObject has implemented the protocol, so OBJC can be used by almost all KVO objects.



The common methods for using KVO operations in OBJC are as follows:


    1. Register the listener for the specified key path: addObserver:forKeyPath:options:context:
    2. Delete the listener for the specified key path: Removeobserver:forkeypath, RemoveObserver:forKeyPath:context:
    3. Callback Listener: ObserveValueForKeyPath:ofObject:change:context:


The use of the KVO is also relatively straightforward:


    1. by AddObserver:forKeyPath:options:context: Registering listeners for the listener (which is usually the data model)
    2. Rewrite the listener's ObserveValueForKeyPath:ofObject:change:context: method


We are upgrading the USER.M


#import "User.h"

@implementation User

-(void)showUserInfo {
     NSLog(@"userName=%@,userAge=%d,essayCount=%d",_name,_age,_blog.essayCount);
}

//Rewrite setBlog
-(void)setBlog:(Blog *)blog{
     _blog=blog;
     //Add monitoring to blog
     [self.blog addObserver:self forKeyPath:@"essayCount" options:NSKeyValueObservingOptionNew context:nil];
}

//Rewrite the observeValueForKeyPath method, and get notified here when the number of blog posts changes
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
     if([keyPath isEqualToString:@"essayCount"]){//Only the balance attribute is processed here
         NSLog(@"keyPath=%@,object=%@,newValue=%.2f,context=%@",keyPath,object,[[change objectForKey:@"new"] floatValue],context);
     }
}

-(void)dealloc{
     NSLog(@"I was destroyed...");
     [self.blog removeObserver:self forKeyPath:@"essayCount"];//Remove monitor
}

@end 


  



Update main.m


 
#import <Foundation/Foundation.h>
#import "Blog.h"
#import "User.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
        User *newUser = [[User alloc] init];
        newUser.name = @"zhangsan";
        newUser.age = 19;
        [newUser showUserInfo];
        
        Blog *newBlog = [[Blog alloc] init];
        newUser.blog = newBlog;
        newBlog.essayCount = 500;
        [newUser showUserInfo];
        newBlog.essayCount = 2000;
        [newUser showUserInfo];
    }
    return 0;
}


New test results


2016-01-11 00:31:51.221 kvc_kvo[46761:703550] username= Zhang San, userage=19,essaycount=0
2016-01-11 00:31:51.223 kvc_kvo[46761:703550] keypath=essaycount,object=<blog:0x100300140>,newvalue= 500.00,context= (NULL)
2016-01-11 00:31:51.223 kvc_kvo[46761:703550] username= Zhang San, userage=19,essaycount=500
2016-01-11 00:31:51.224 kvc_kvo[46761:703550] keypath=essaycount,object=<blog:0x100300140>,newvalue= 2000.00,context= (NULL)
2016-01-11 00:31:51.224 kvc_kvo[46761:703550] username= Zhang San, userage=19,essaycount=2000
2016-01-11 00:31:51.224 kvc_kvo[46761:703550] I was destroyed ....


Ha ha... This is a typical KVO application.





[Objective-c] 021 KVC, KVO


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.