IOS-KVC\KVO principle

Source: Internet
Author: User
Tags key string

Original address: Http://blog.csdn.net/wzzvictory/article/details/9674431KVC (key-value coding) key value code, similar to map,          Provides a mechanism to access an object instance variable using a string instead of an accessor method. KVO (Key-value observing) key-value observation provides a mechanism for notifying the current object when other object properties have been modified. 1. Key and key PATHKVC define a mechanism for accessing object properties by name, and the main ways to support such access are:
    1. -(ID) Valueforkey: (NSString *) key;
    2. -(void) SetValue: (ID) value Forkey: (NSString *) key;
    3. -(ID) Valueforkeypath: (NSString *) KeyPath;
    4. -(void) SetValue: (ID) value Forkeypath: (NSString *) KeyPath;

2, point syntax and KVC in the class that implements accessor methods, using point syntax and KVC to access objects is not very different, they can be arbitrarily mixed. However, in a class that does not have accessor methods, point syntax is not available, and KVC has an advantage.
3. The collection accessor method in a one-to-many relationship (To-many) Most of the properties we use are a pair of relationships (To-one), such as the name attribute in the person class, and everyone has only one name. But there is a one-to-many relationship, such as the person has a friendsname attribute, which is a collection (in Objective-c can be nsarray,nsset, etc.), save the name of all the Friends of a man. When manipulating the contents of a one-to-many property, we have two choices: the ① indirection first takes the collection property through the KVC method, and then the elements in the collection are manipulated through the collection properties. ② Direct Operation Apple provides us with some method templates that we can implement in a prescribed format to achieve the purpose of accessing elements in a collection's properties. The corresponding method for an ordered set is as follows:
    1. -countof<key>
    2. Must be implemented, corresponding to the basic method of Nsarray count:
    3. -objectin<key>atindex:
    4. -<key>atindexes:
    5. Both of these must implement a method that corresponds to Nsarray objectatindex: and objectsatindexes:
    6. -get<key>:range:
    7. is not required, but can be implemented to improve performance, which corresponds to the Nsarray method Getobjects:range:
    8. -insertobject:in<key>atindex:
    9. -insert<key>:atindexes:
    10. Both must implement a method similar to Nsmutablearray Insertobject:atindex: and insertobjects:atindexes:
    11. -removeobjectfrom<key>atindex:
    12. -remove<key>atindexes:
    13. Both must implement a method similar to Nsmutablearray Removeobjectatindex: and removeobjectsatindexes:
    14. -replaceobjectin<key>atindex:withobject:
    15. -replace<key>atindexes:with<key>:
Unordered collections correspond to the following methods:

    1. -countof<key>
    2. Must be implemented, corresponding to the basic method of Nsarray count:
    3. -objectin<key>atindex:
-<key>atindexes:
Both of these must implement a method that corresponds to Nsarray objectatindex: and objectsatindexes:
-get<key>:range:
is not required, but can be implemented to improve performance, which corresponds to the Nsarray method Getobjects:range:

-insertobject:in<key>atindex:
-insert<key>:atindexes:
Both must implement a method similar to Nsmutablearray Insertobject:atindex: and insertobjects:atindexes:
-removeobjectfrom<key>atindex:
-remove<key>atindexes:
Both must implement a method similar to Nsmutablearray Removeobjectatindex: and removeobjectsatindexes:
-replaceobjectin<key>atindex:withobject:
-replace<key>atindexes:with<key>:
4, Key-value verification (Key-value Validation) KVC provides a way to verify that the value corresponding to the key is available:

    1. -(BOOL) Validatevalue: (inout ID *) iovalue forkey: (NSString *) Inkey error: (Out nserror * *) Outerror;
The default implementation of this method is to invoke a method of the following format:
    1. -(BOOL) Validate<key>:error:
For example, the property name corresponds to the method:

    1. -(BOOL) Validatename: (ID *) Iovalue error: (Nserror * __autoreleasing *) Outerror {
    2. Implementation specific code.
    3. return ...;
    4. }
This gives us an opportunity to correct the error. It should be noted that KVC does not automatically invoke the key-value validation method, which means that we need to verify it manually. But some techniques, such as CoreData, are automatically invoked. 5. KVC support for numerical and structural body Properties KVC can automatically package or unpack data of numerical or structural size into NSNumber or Nsvalue objects for adaptation purposes.
For example, the person class has a nsinteger type of age property ① modified value We set the value of the age property by using the KVC technique as follows:
    1. [Person Setvalue:[nsnumber Numberwithinteger:5] forkey:@ ' age ';
What we assign to age is a NSNumber object, KVC automatically converts the NSNumber object to a Nsinteger object, and then calls the appropriate accessor method to set the value of age.
② Get value Similarly, get the Age property value in the following way:
    1. [Person valueforkey:@ ' age '];
At this point, the value of age is returned as a nsnumber. What you need to know is, when is the return of NSNumber, and when is the Nsvalue returned? ③ the types of data that can be used with the NSNumber encapsulation NSNumber are:
  1. + (NSNumber *) Numberwithchar: (char) value;
  2. + (NSNumber *) Numberwithunsignedchar: (unsigned char) value;
  3. + (NSNumber *) Numberwithshort: (short) value;
  4. + (NSNumber *) Numberwithunsignedshort: (unsigned short) value;
  5. + (NSNumber *) Numberwithint: (int) value;
  6. + (NSNumber *) Numberwithunsignedint: (unsigned int) value;
  7. + (NSNumber *) Numberwithlong: (long) value;
  8. + (NSNumber *) Numberwithunsignedlong: (unsigned long) value;
  9. + (NSNumber *) Numberwithlonglong: (Long long) value;
  10. + (NSNumber *) Numberwithunsignedlonglong: (unsigned long long) value;
  11. + (NSNumber *) Numberwithfloat: (float) value;
  12. + (NSNumber *) Numberwithdouble: (double) value;
  13. + (NSNumber *) Numberwithbool: (BOOL) value;
  14. + (NSNumber *) Numberwithinteger: (Nsinteger) value ns_available (10_5, 2_0);
  15. + (NSNumber *) Numberwithunsignedinteger: (Nsuinteger) value ns_available (10_5, 2_0);
In short, there are some common numerical data. ④ uses the Nsvalue package Nsvalue primarily for data processing of structure size, which itself provides support for the following centralized structure:
    1. + (Nsvalue *) Valuewithcgpoint: (cgpoint) point;
    2. + (Nsvalue *) Valuewithcgsize: (cgsize) size;
    3. + (Nsvalue *) Valuewithcgrect: (cgrect) rect;
    4. + (Nsvalue *) Valuewithcgaffinetransform: (cgaffinetransform) transform;
    5. + (Nsvalue *) Valuewithuiedgeinsets: (uiedgeinsets) insets;
    6. + (Nsvalue *) Valuewithuioffset: (uioffset) insets Ns_available_ios (5_0);

There are only a limited 6 kinds! What about other custom constructs? Don't worry, any structure can be converted into Nsvalue object, the concrete implementation method see another article: http://blog.csdn.net/wzzvictory/article/details/86144336, The set operator (Collection Operators) set operator is a special key Path that can be passed as a parameter to Valueforkeypath: method, note that only this method, if passed to the Valueforkey: method to ensure that your program crashes. The operator is a special string that begins with @, as shown in the following: ① simple set operator simple set operator Common @avg, @count, @max, @min, @sum5 kind of, all mean nothing. Custom is not supported at this time. There is an object of the collection class: Transactions, which stores an instance of the transaction class, which has three properties: Payee,amount,date. Here's an example of how to use these operators: to get the average of amount, you can:
    1. NSNumber *transactionaverage = [Transactions valueforkeypath:@ "@avg. Amount"];
To get the number of elements in the Transactions collection, you can do this:

    1. NSNumber *numberoftransactions = [Transactions valueforkeypath:@ "@count"];
What is needed is that @count is a special one of these set operators because it is not on the correct, because it is easy to understand. The ② object operator is slightly more complex than the set operator and can return the specified content as an array, with a total of two
    1. @distinctUnionOfObjects
    2. @unionOfObjects
Their return values are Nsarray, the difference being that the elements returned by the former are unique and are the result of going back, and the latter returning elements are complete works. Use the following:
    1. Nsarray *payees = [Transactions valueforkeypath:@ "@distinctUnionOfObjects. Payee"];
    2. Nsarray *payees = [Transactions valueforkeypath:@ "@unionOfObjects. Payee"];
The former will return the payee's name after repetition, which returns the name of all the payee directly. The ③array and set operators are more complicated, saying that the collection contains a collection, and we execute the following code:
    1. Create the array that contains additional arrays.
    2. Self.arrayoftransactionsarray = [Nsmutablearray array];
    3. Add the array of objects used in the above examples.
    4. [Arrayoftransactionsarray addobject:transactions];
    5. ADD a second array of objects; This array contains alternate values.
    6. [Arrayoftransactionsarrays addobject:moretransactions];
Get a collection of contained collections: Arrayoftransactionsarray at this point, if we want to manipulate the elements in the collection contained in Arrayoftransactionsarray, we can use the following three operators:
    1. @distinctUnionOfArrays
    2. @unionOfArrays
    3. @distinctUnionOfSets
The first two sets are arrays, and the latter set is sets. Because the elements in the sets are inherently unique, there is no corresponding @unionofsets operator. Examples of their usage are as follows:
    1. Nsarray *payees = [Arrayoftransactionsarrays valueforkeypath:@ "@unionOfArrays. Payee"];

Third, the implementation of principle 1, KVC How to access the property value KVC to some extent provides an alternative to accessors. But the accessor method is a good thing, so long as it is possible, KVC also try to work with the help of the accessor method. To set or Return object properties, KVC uses the following techniques in order: ① checks for the presence of-、-is (valid only for Boolean values) or-get accessor methods, and, if possible, returns a value using these methods, checking for the existence of a method named-set: and using it to set the value. For-get and-set: Method, capitalize the first letter of the key string and match the cocoa method name, ② if the above method is not available, check the name-_,-_is (valid only for Boolean values),-_get, and-_set: method; ③ If no accessor method is found, You can try direct access to instance variables. The instance variable can be named: or _;④ if it is still found, call Valueforundefinedkey: And Setvalue:forundefinedkey: Method. The default implementations of these methods are throwing exceptions, and we can rewrite them as needed. 2, KVC/KVO realization principle key value code and key value observation is based on the isa-swizzling technology to achieve, mainly based on the runtime's strong dynamic ability. This passage is quoted from an article on the Internet: http://blog.csdn.net/kesalin/article/details/8194240 when an object of a class is first observed, a derived class of that class is dynamically created at run time by the system. Overrides the setter method of any observed property in the base class in this derived class.
Derived classes implement a true notification mechanism in the overridden setter method, just as the previous manual implementation of the key-value observation. This is done by invoking the setter method based on the setting property, and by overriding the notification mechanism required by the KVO. Of course, if you want to change the property value by following the KVO property setting, you cannot implement KVO if you modify only the member variable that corresponds to the property.
The derived class also overrides the class method to "spoof" The Outside caller, which is the first of the classes. The system then points the ISA pointer of the object to the newly-born derived class, so that the object becomes an object of that derived class, so that the call to the setter on that object invokes the overridden setter, activating the key-value notification mechanism. In addition, derived classes override the Dealloc method to free resources. The original writing is very good, but also give an explanatory example, we can go to see. In a previous article that introduced OBJECTIVE-C classes and meta-classes: http://blog.csdn.net/wzzvictory/article/details/8592492, the ISA pointer is actually the class's meta-class, If the previous class name is: Person, then the class name after the runtime changes will become: Nskvonotifying_person. The new Nskvonotifying_person class overrides the following method: Adds a set method for the listener's properties, Class,dealloc,_iskvoa. ①class overrides the class method to return the same content that was used before overriding the inheriting class when we called it. Print the following:
    1. NSLog (@ "self->isa:%@", Self->isa);
    2. NSLog (@ ' self class:%@ ', [self class]);

Before setting up KVO monitoring, the result is:

    1. Self->isa:person
    2. Self Class:person

After the KVO monitoring is established, the result is:

    1. Self->isa:nskvonotifying_person
    2. Self Class:person


    1. Self->isa:nskvonotifying_person
    2. Self Class:person
This is also a difference between the ISA pointer and the class method, which you should pay attention to when using. ② overriding the set method the new class overrides the corresponding set method in order to add a call to the other two methods in the Set method:
    1. -(void) Willchangevalueforkey: (NSString *) key
    2. -(void) Didchangevalueforkey: (NSString *) key
where the Didchangevalueforkey: method is responsible for invoking:

    1. -(void) Observevalueforkeypath: (NSString *) keypath
    2. Ofobject: (ID) object
    3. Change: (nsdictionary *) change
    4. Context: (void *) context
method, this is the principle of KVO implementation! If there is no accessor method, the-setvalue:forkey method calls directly:
    1. -(void) Willchangevalueforkey: (NSString *) key
    2. -(void) Didchangevalueforkey: (NSString *) key
If you do not use the key-value encoding and do not use an appropriately named accessor method, we only need to display the call to the above two methods, you can also use the kvo!to summarize, there are three ways to use KVO:1) Use of KVCusing KVC, if there is an accessor method, the runtime calls Will/didchangevalueforkey: Method in the accessor method;The accessor method is not used, and the runtime calls the Will/didchangevalueforkey: method in the Setvalue:forkey method. 2) Accessor methodThe runtime overrides the accessor method call Will/didchangevalueforkey: Method. Therefore, the KVO can also be heard when the accessor method is called directly to change the property value. 3) Show Call Will/didchangevalueforkey: Method. in short, want to use KVO, as long as there is will/didchangevalueforkey: Method can be. ③_iskvoa This private method is estimated to be used to indicate that the class is a class that the KVO mechanism claims. Iv. Advantages and Disadvantages 1, the advantages of ① can be greatly simplified code example online a lot, this does not give ② can with scripting language very good match Caishuxueqian, did not learn AppleScript and other scripting language, so did not be able to deeply appreciate the advantages. 2, shortcomings KVC shortcomings are not obvious, mainly KVO, the details can refer to this article: http://www.mikeash.com/pyblog/ Key-value-observing-done-right.html Core idea is to say KVO callback mechanism, can not pass a selector or block as a callback, but must rewrite-addobserver:forkeypath:o Ptions:context: A series of problems caused by the method. In order to solve this problem, the author also personally implemented a Makvonotificationcenter class, code see github:https://github.com/mikeash/ Makvonotificationcenter But personally think this is just Apple do kvo not perfect, not a flaw. Reference Document: http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/keyvaluecoding/articles/ keyvaluecoding.html#//apple_ref/doc/uid/10000107-sw1http://blog.csdn.net/kesalin/article/details/8194240
Wangzz Original Address: http://blog.csdn.net/wzzvictory/article/details/9674431




IOS-KVC\KVO principle

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.