IOS Development Series -- Objective-C: KVC, KVO, -- objective-ckvc

Source: Internet
Author: User

IOS Development Series -- Objective-C: KVC, KVO, -- objective-ckvc
Overview

Because ObjC is mainly designed based on Smalltalk, it has many dynamic features similar to Ruby and Python, such as dynamic types, dynamic loading, and dynamic binding. Today, we will introduce the key-value encoding (KVC) and key-value listening (KVO) features in ObjC:

KVC

We know that in C #, attributes of an object can be read and written through reflection. Sometimes this method is very convenient, because you can dynamically control an object using strings. In fact, due to the language characteristics of ObjC, you can perform dynamic attribute read/write without any operations at the root. This method is Key Value Coding (KVC ).

The KVC operation method is provided by the NSKeyValueCoding protocol, while NSObject implements this Protocol. That is to say, all objects in ObjC support KVC operations. The common KVC operation methods are as follows:

  • Dynamic settings:SetValue: property value forKey: property name(For simple paths ),SetValue: forKeyPath: attribute path(Used for compound paths. For example, if Person has an Account-type attribute, person. account is a compound attribute)
  • Dynamic reading:ValueForKey: attribute name,ValueForKeyPath: attribute name(Used for compound paths)

The following uses an example to understand KVC

Account. h

//// Account. h // KVCAndKVO /// Created by Kenshin Cui on 14-2-16. // Copyright (c) 2014 Kenshin Cui. all rights reserved. // # import <Foundation/Foundation. h> @ interface Account: NSObject # pragma mark-attribute # pragma mark balance @ property (nonatomic, assign) float balance; @ end

Account. m

//// Account. m // KVCAndKVO /// Created by Kenshin Cui on 14-2-16. // Copyright (c) 2014 Kenshin Cui. all rights reserved. // # import "Account. h "@ implementation Account @ end

Person. h

/// Person. h // KVCAndKVO /// Created by Kenshin Cui on 14-2-16. // Copyright (c) 2014 Kenshin Cui. all rights reserved. // # import <Foundation/Foundation. h> @ class Account; @ interface Person: NSObject {@ private int _ age;} # pragma mark-attribute # pragma mark name @ property (nonatomic, copy) NSString * name; # pragma mark Account @ property (nonatomic, retain) account * Account; # pragma mark-public method # pragma mark displays personnel information-(void) showMessage; @ end

Person. m

/// Person. m // KVCAndKVO /// Created by Kenshin Cui on 14-2-16. // Copyright (c) 2014 Kenshin Cui. all rights reserved. // # import "Person. h "@ implementation Person # pragma mark-public method # pragma mark display personnel information-(void) showMessage {NSLog (@" name = % @, age = % d ", _ name, _ age) ;}@ end

Main. m

//// Main. m // KVCAndKVO /// Created by Kenshin Cui on 14-2-16. // Copyright (c) 2014 Kenshin Cui. all rights reserved. // # import <Foundation/Foundation. h> # import "Person. h "# import" Account. h "int main (int argc, const char * argv []) {@ autoreleasepool {Person * person1 = [[Person alloc] init]; [person1 setValue: @ "Kenshin" forKey: @ "name"]; [person1 setValue: @ 28 forKey: @ "age"]; // note that even if a private variable can still access [person1 showMessage]; // result: name = Kenshin, age = 28 NSLog (@ "person1's name is: % @, age is: % @ ", person1.name, [person1 valueForKey: @" age "]); // result: person1's name is: Kenshin, age is: 28 Account * account1 = [[Account alloc] init]; person1.account = account1; // note that you must assign values to the account attribute in this step; otherwise, the following values cannot be assigned by path, because the account is nil, of course this step can also be written as: [person1 setValue: account1 forKeyPath: @ "account"]; [person1 setValue: @ 100000000.0 forKeyPath: @ "account. balance "]; NSLog (@" person1's balance is: %. 2f ", [[person1 valueForKeyPath: @" account. balance "] floatValue]); // result: person1's balance is: 100000000.00} return 0 ;}

KVC is easy to use, but how does it find an attribute for reading? Specific Search rules (assuming that KVC is used to read ):

  • If the property is set dynamically, the setA method is called first. If this method is not used, the member Variable _ a is searched first. If it still does not exist, the member variable a is searched, if not found, the setValue: forUndefinedKey: Method of the class will be called (note that the methods, member variables are private or public during the search process can be correctly set );
  • For dynamic attribute reading, the call of method a (the getter method of attribute a) is preferred. If no value is found, the member Variable _ a is preferentially searched, if it still does not exist, search for member variable a. If it still does not exist, the valueforUndefinedKey of this class will be called: method (whether these methods, member variables are private or public, they can be correctly read during the search process );
KVO

We know that there is a two-way binding mechanism in WPF and Silverlight. If the data model is modified, it will be immediately reflected in the UI view, similar front-end frameworks based on MVVM design patterns, such as Knockout. js. In fact, ObjC originally supports this mechanism, which is called Key Value Observing (KVO ). KVO is actually an observer mode, which can easily achieve the separation of view components and data models. When the value of the data model changes, the view components used as listeners will be stimulated, when the listener is triggered, the listener itself is called back. To implement KVO in ObjC, you must implement the NSKeyValueObServing protocol. Fortunately, NSObject has implemented this protocol, so KVO can be used for all ObjC objects.

Common methods for using KVO in ObjC are as follows:

  • Register the listener for the specified Key path:AddObserver: forKeyPath: options: context:
  • Delete the listener of the specified Key path:RemoveObserver: forKeyPath,RemoveObserver: forKeyPath: context:
  • Callback listener:ObserveValueForKeyPath: ofObject: change: context:

KVO is easy to use:

Since we have not introduced IOS interface programming, we will continue to expand it on the basis of the above example. If our account balance changes, we hope that users will be notified in a timely manner. At this time, the Account is our Monitored object and requires the Person to register the listener for it (using addObserver: forKeyPath: options: context :); while the Person as the listener needs to rewrite its observeValueForKeyPath: ofObject: change: context: method. When the listener balance changes, the listener's Person listener method (observeValueForKeyPath: ofObject: change: context :) is called back :). The following code simulates the above process:

Account. h

//// Account. h // KVCAndKVO /// Created by Kenshin Cui on 14-2-16. // Copyright (c) 2014 Kenshin Cui. all rights reserved. // # import <Foundation/Foundation. h> @ interface Account: NSObject # pragma mark-attribute # pragma mark balance @ property (nonatomic, assign) float balance; @ end

Account. m

//// Account. m // KVCAndKVO /// Created by Kenshin Cui on 14-2-16. // Copyright (c) 2014 Kenshin Cui. all rights reserved. // # import "Account. h "@ implementation Account @ end

Person. h

/// Person. h // KVCAndKVO /// Created by Kenshin Cui on 14-2-16. // Copyright (c) 2014 Kenshin Cui. all rights reserved. // # import <Foundation/Foundation. h> @ class Account; @ interface Person: NSObject {@ private int _ age;} # pragma mark-attribute # pragma mark name @ property (nonatomic, copy) NSString * name; # pragma mark Account @ property (nonatomic, retain) account * Account; # pragma mark-public method # pragma mark displays personnel information-(void) showMessage; @ end

Person. m

/// Person. m // KVCAndKVO /// Created by Kenshin Cui on 14-2-16. // Copyright (c) 2014 Kenshin Cui. all rights reserved. // # import "Person. h "# import" Account. h "@ implementation Person # pragma mark-public method # pragma mark display personnel information-(void) showMessage {NSLog (@" name = % @, age = % d ", _ name, _ age) ;}# pragma mark sets up a person Account-(void) setAccount :( account *) account {_ account = Account; // adds a listener to the Account [self. account addObserver: self forKeyPath: @ "balance" options: NSKeyValueObservingOptionNew context: nil] ;}# pragma mark-override method # pragma mark override observeValueForKeyPath method, when the account balance changes, you will be notified here-(void) observeValueForKeyPath :( NSString *) keyPath ofObject :( id) object change :( NSDictionary *) change context :( void *) context {if ([keyPath isinclutostring: @ "balance"]) {// here, only the NSLog (@ "keyPath =%@, object =%@, newValue = % of the balance attribute is processed. 2f, context = % @ ", keyPath, object, [[change objectForKey: @" new "] floatValue], context) ;}# pragma mark rewrite destruction method-(void) dealloc {[self. account removeObserver: self forKeyPath: @ "balance"]; // remove the listener // [super dealloc]; // note that ARC is enabled, which does not need to be called here} @ end

Main. m

//// Main. m // KVCAndKVO /// Created by Kenshin Cui on 14-2-16. // Copyright (c) 2014 Kenshin Cui. all rights reserved. // # import <Foundation/Foundation. h> # import "Person. h "# import" Account. h "int main (int argc, const char * argv []) {@ autoreleasepool {Person * person1 = [[Person alloc] init]; person1.name = @" Kenshin "; account * account1 = [[Account alloc] init]; account1.balance = 100000000.0; person1.account = account1; account1.balance = 200000000.0; // note that executing this step triggers the listener callback function observeValueForKeyPath: ofObject: change: context: // result: keyPath = balance, object = <Account: 0x100103aa0>, newValue = 200000000.00, context = (null)} return 0 ;}

In the above Code, we added a listener to the balance attribute of the account when assigning an account to a person, and output the listener information in the listener callback method, at the same time, the listener is removed when the object is destroyed, forming a typical KVO application.


What is the role of Objective-C-language KVC's indirect access to object attributes?

We recommend that you use Baidu. the keyword is "kvc kvo". There must be a reason for the simple description on cnblogs.
 
Can I use kvc/kvo to add an observer for any attribute?

Kvc/kvo is too simple or difficult. I don't feel like I'm asking...

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.