In the daily development, we can through breakpoint debugging, source view, LLDB debugging to explore the principle of technology, in fact, the document view is also a very important means. KVC(key-value Coding) is a common technology in our daily development, so how to achieve the underlying? We will start with the key-value Coding Programming Guide. Of course, you can search the Apple Documentation Archive for other technologies on the first page

1. Introduction to KVC

Key-value coding is a mechanism enabled by the NSKeyValueCoding informal protocol that objects adopt to provide indirect access to their properties. As you can see from the documentation, KVC is a mechanism that enables direct access to object properties through the NSKeyValueCoding protocol.

2, the principle of

Part of its principle is explained in English on the official document. I am a porter here. So basically there are two methods: valueForKey: and setValue forKey:.

2.1, getter method – valueForKey:

  • 1. Find out if there are anyget<Key>, <key>, is<Key>, or _<key>If there is a jump to 5, there is no next step
  • 2. Determine if it isNSArray
  • 2.1 Finding whether to implementcountOf<Key>orobjectIn<Key>AtIndex:Method, if there is, call the method and return the value, if there is no, go 3
  • 3. WhetherNSSet
  • 3.1 Finding whether to implementcountOf<Key>, enumeratorOf<Key>, and memberOf<Key>:Method, if there is, call the method and return the value, not go 4·
  • 4. Non-collection types
    • 4.1 judgmentaccessInstanceVariablesDirectly:(Whether member variables can be accessed directly: YES is returned by default) Whether the method returns YES
    • 4.2 looking for_<key>, _is<Key>, <key>, or is<Key>These member variables
    • 4.3 If yes, obtain the value of the instance variable and go to Step 5
  • 5. Details
    • 5.1 If the retrieved property value is an object pointer, only the result needs to be returned
    • 5.2 If the value isNSNumberSupported scalar types are stored inNSNumberInstance and return
    • 5.3 If the value isNSNumberUnsupported scalar types are converted toNSValueObject and return
  • 6. An errorvalueForUndefinedKey:

Setmethod -setValue :forKey:

  • 1. Simple access: Find out if it existsset<Key>:or_set<Key>Method, if any, then call and complete; If you don’t go into 2
  • 2. Instance variable access:
    • 2.1 Judge this methodaccessInstanceVariablesDirectlyWhether to returnYES
    • 2.2 Determine whether these instance variables exist_<key>, _is<Key>, <key>, or is<Key>
    • 2.3 Directly assign values to the following member variables if they are found in order and complete
  • Error: if 1 and 2 were found, then error:setValue:forUndefinedKey:

3. KVC uses tips and notes

3.1. Automatic conversion type

If the value type is the number or struct type of the NSString class, the value type is translated into __NSCFNumber and NSConcreteValue. Eg: Person class implementation

typedef struct {
    float x, y, z;
} ThreeFloats;

@interface Person : NSObject
@property (nonatomic, copy) NSString *subject;
@property (nonatomic, assign) int  age;
@property (nonatomic, assign) BOOL sex;
@property (nonatomic) ThreeFloats  threeFloats;

@end
Copy the code

call

Person *person = [[Person alloc] init]; // 1: KVC automatically converts type NSLog(@"******1: kvC-int -> NSNumber - structure ******");

    [person setValue:@18 forKey:@"age"]; // The above expression should be familiar to everyone! But this is ok, right? [personsetValue:@"20" forKey:@"age"]; // int - string
    NSLog(@"% @ - % @",[person valueForKey:@"age"],[[person valueForKey:@"age"] class]); //__NSCFNumber [personsetValue:@"20" forKey:@"sex"]; //Bool - string NSLog(@"% @ - % @",[person valueForKey:@"sex"],[[person valueForKey:@"sex"] class]); //__NSCFNumber ThreeFloats floats = {1., 2., 3.}; NSValue *value = [NSValue valueWithBytes:&floats objCType:@encode(ThreeFloats)]; [personsetValue:value forKey:@"threeFloats"];
    NSLog(@"% @ - % @",[person valueForKey:@"threeFloats"],[[person valueForKey:@"threeFloats"] class]); //NSConcreteValueCopy the code

3.2. Set a null value

    NSLog(@"******2: set null value ******");
    [person setValue:nil forKey:@"age"]; / / the age is nil/personsetValue:nil forKey:@"subject"]; //subject will not go - NSNumber - NSValue is not supported by NSStringCopy the code

The key cannot be found

    NSLog(@"******3: 找不到的 key******");
    [person setValue:nil forKey:@"KC"]; 
Copy the code

3.4. The key cannot be found

    NSLog(@"******4: value - Key not found ******");
    NSLog(@"% @",[person valueForKey:@"KC"]);
Copy the code

3.5. Key value verification

KVC provides key value verification API – (BOOL)validateValue:(inout id _Nullable * _Nonnull)ioValue forKey:(NSString *)inKey error:(out NSError **)outError;

    NSLog(@"******5: key validation ******");
    NSError *error;
    NSString *name = @"Cooci";
    if(! [person validateValue:&nameforKey:@"names" error:&error]) {
        NSLog(@"% @",error);
    }else{
        NSLog(@"% @",[person valueForKey:@"name"]);
    }
Copy the code

Write in the last

If this article is helpful to you, please click a thumbs-up, little brother here thank you!