Differences between KVC and KVO in iOS and iOSKVCKVO

Source: Internet
Author: User

Differences between KVC and KVO in iOS and iOSKVCKVO

The two concepts KVC and KVO are often seen in iOS development, which may be confused.

KVC (Key Value Coding) 1> Overview

KVC: Key Value Coding, which is used to indirectly access instance variables.

KVC provides a mechanism to access an object instance variable by using a string (Key) instead of an accessor method.

2> some KVC source code (header files)
 1 // NSKeyValueCoding.h 2 @interface NSObject(NSKeyValueCoding) 3  4 + (BOOL)accessInstanceVariablesDirectly; 5  6 - (nullable id)valueForKey:(NSString *)key; 7 - (void)setValue:(nullable id)value forKey:(NSString *)key; 8 - (BOOL)validateValue:(inout id __nullable * __nonnull)ioValue forKey:(NSString *)inKey error:(out NSError **)outError; 9 10 - (NSMutableArray *)mutableArrayValueForKey:(NSString *)key;11 12 - (NSMutableOrderedSet *)mutableOrderedSetValueForKey:(NSString *)key NS_AVAILABLE(10_7, 5_0);13 14 - (NSMutableSet *)mutableSetValueForKey:(NSString *)key;15 16 - (nullable id)valueForKeyPath:(NSString *)keyPath;17 - (void)setValue:(nullable id)value forKeyPath:(NSString *)keyPath;18 - (BOOL)validateValue:(inout id __nullable * __nonnull)ioValue forKeyPath:(NSString *)inKeyPath error:(out NSError **)outError;19 - (NSMutableArray *)mutableArrayValueForKeyPath:(NSString *)keyPath;20 - (NSMutableOrderedSet *)mutableOrderedSetValueForKeyPath:(NSString *)keyPath NS_AVAILABLE(10_7, 5_0);21 - (NSMutableSet *)mutableSetValueForKeyPath:(NSString *)keyPath;22 23 - (nullable id)valueForUndefinedKey:(NSString *)key;24 - (void)setValue:(nullable id)value forUndefinedKey:(NSString *)key;25 - (void)setNilValueForKey:(NSString *)key;26 - (NSDictionary<NSString *, id> *)dictionaryWithValuesForKeys:(NSArray<NSString *> *)keys;27 - (void)setValuesForKeysWithDictionary:(NSDictionary<NSString *, id> *)keyedValues;28 29 @end30 31 @interface NSArray<ObjectType>(NSKeyValueCoding)32 33 - (id)valueForKey:(NSString *)key;34 - (void)setValue:(nullable id)value forKey:(NSString *)key;35 36 @end37 38 @interface NSDictionary<KeyType, ObjectType>(NSKeyValueCoding)39 40 - (nullable ObjectType)valueForKey:(NSString *)key;41 42 @end43 44 @interface NSMutableDictionary<KeyType, ObjectType>(NSKeyValueCoding)45 46 - (void)setValue:(nullable ObjectType)value forKey:(NSString *)key;47 48 @end49 50 @interface NSOrderedSet<ObjectType>(NSKeyValueCoding)51 52 - (id)valueForKey:(NSString *)key NS_AVAILABLE(10_7, 5_0);53 - (void)setValue:(nullable id)value forKey:(NSString *)key NS_AVAILABLE(10_7, 5_0);54 55 @end56 57 @interface NSSet<ObjectType>(NSKeyValueCoding)58 59 - (id)valueForKey:(NSString *)key;60 - (void)setValue:(nullable id)value forKey:(NSString *)key;61 62 @end

The class contains extensions for NSObject, NSArray, NSDictionary, NSMutableDictionary, NSOrderedSet, and NSSet.

- (id)valueForKey:(NSString *)key;- (void)setValue:(nullable id)value forKey:(NSString *)key;

That is to say, basically all objects in Objective-C areSupport for KVCThe operation includes the above two methods, dynamic reading and dynamic setting.

3> access attributes through KVC key-value Encoding

① Key value search

1 [stu setValue:@"xiaoqiang" forKey:@"name"]; 2 [stu setValue:@"boy" forKey:@"gender"];3 [stu setValue:@24 forKey:@"age"]; 4 5 NSLog(@"name = %@, gender = %@, age = %@", [stu valueForKey:@"name"], [stu valueForKey:@"gender"], [stu valueForKey:@"age"]);

② Path search

1 Teacher * tea = [[Teacher alloc] init]; 2 stu. teacher = tea; 3 [stu setValue: @ "fangfang" forKeyPath: @ "teacher. name "]; 4 5 // search for 6 NSLog (@" teacherName = % @ ", [stu valueForKeyPath: @" teacher. name "]);

③ Assign values to multiple attributes at the same time

1 NSDictionary * dict =@{ 2 @ "name": @ "fangfang", 3 @ "gender": @ "girl", 4 @ "age": @ 18, 5 @ "holobby": @ "fangfang" 6}; 7 Student * stu2 = [Student alloc] init]; 8 9 // assign 10 [stu2 setValuesForKeysWithDictionary: dict] to multiple attributes at the same time; 11 12 NSLog (@ "name =%@, gender =%@, age = % ld ", stu2.name, stu2.gender, stu2.age );
4> KVC throw an exception

① When KVC is used to set a value object

If the current class does not find the Key value of the object, the system will automatically call setValue: forUndefinedKey: Method

The default implementation of this method is to throw an exception. If you do not want to throw an exception, rewrite this method.

1 // rewrite 2 // use KVC to set the value object 3-(void) setValue :( id) value forUndefinedKey :( NSString *) key4 {5 NSLog (@ "Key does not exist: % @ ", key); 6}

② When using the KVC Value

If the corresponding Key value is not found for the current class, the system will automatically call valueForUndefinedKey: Method

The default implementation of this method is to throw an exception. If you do not want to throw an exception, rewrite this method.

1 // rewrite 2 // when KVC is used, 3-(id) valueForUndefinedKey :( NSString *) key4 {5 return nil; 6}
5> Implementation Mechanism of KVC

KVC uses the following techniques in sequence:

  • Check whether the getter method-<key> or setter method-set <key>: exists;
  • If no such method is available, check whether there are instance variables named-_ <key> and <key>;
  • If not found, call valueForUndefinedKey: And setValue: forUndefinedKey: method. The default implementation of these methods throws an exception. We can rewrite them as needed.
KVC (Key Value Observer)

1> Overview

KVO :( Key Value Observer) is a concrete implementation of the Observer design pattern.

KVO trigger mechanism: one object (observer) is used to monitor whether a property of another object (observer) changes. If the property to be monitored changes, will trigger a method of the observer (the method name is fixed, similar to the proxy method)

2> some NSKeyValueObserving. h extended NSObject code

 1 @interface NSObject(NSKeyValueObserving) 2  3 - (void)observeValueForKeyPath:(nullable NSString *)keyPath ofObject:(nullable id)object change:(nullable NSDictionary<NSString*, id> *)change context:(nullable void *)context; 4  5 @end 6  7 @interface NSObject(NSKeyValueObserverRegistration) 8  9 - (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(nullable void *)context;10 - (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath context:(nullable void *)context NS_AVAILABLE(10_7, 5_0);11 - (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath;12 13 @end

We can see from the extension name thatUse KVCYou need to register the listener and delete the listener. The observeValueForKeyPath callback method is required during the monitoring process.

3> procedure

Register The Observer (specify the observer and the observed attribute for the observer)

1 // KVO key value observation, is the Observer Design Mode 2 @ interface ViewController () 3 4 // observe the changes of the variable array (it is not recommended to observe the array in Apple's official documentation) 5 @ property (nonatomic, strong) NSMutableArray * array; 6 7 @ end 8 9-(void) viewDidLoad {10 [super viewDidLoad]; 11 // Do any additional setup after loading the view, typically from a nib.12 13 self. array = [NSMutableArray array]; 14 15 // Step 1: Register observer 16 // parameter 1: added observer object 17 // parameter 2: key18 of the string id // parameter 3: 19/* 20 NSKeyValueObservingOptionNew = 0x01 key or value triggers 21 NSKeyValueObservingOptionOld = 0x0222 conflict = 0x0423 conflict = 0x0824 */25 // parameter 4: the text content is generally nil26 [self addObserver: self forKeyPath: @ "array" options: NSKeyValueObservingOptionNew context: nil]; 27}

Callback Implementation Method

1 // Step 2: Implement callback 2-(void) observeValueForKeyPath :( NSString *) keyPath ofObject :( id) object change :( NSDictionary <NSString *, id> *) change context :( void *) context 3 {4 5 NSLog (@ "keyPath = % @", keyPath); 6 NSLog (@ "object = % @", object ); 7 NSLog (@ "change = % @", change); 8 9 // You can refresh the UI 10}

Trigger callback method (observed attribute changes)

1 // Step 2: Implement callback 2-(void) observeValueForKeyPath :( NSString *) keyPath ofObject :( id) object change :( NSDictionary <NSString *, id> *) change context :( void *) context 3 {4 5 NSLog (@ "keyPath = % @", keyPath); 6 NSLog (@ "object = % @", object ); 7 NSLog (@ "change = % @", change); 8 9 // You can refresh the UI 10}

Remove observer

You need to delete the observer when you do not need it. I will only remove it when the view is about to disappear.

1 // when the view is about to disappear 2-(void) viewWillDisappear :( BOOL) animated3 {4 // you need to delete it 5 [self removeObserver: self forKeyPath: @ "array"]; 6}

 

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.