Summary and difference between KVC, KVO, NSNotification, delegate in iOS
1. KVC refers to NSKeyValueCoding, an informal Protocol, which provides a mechanism to indirectly access the properties of an object. Instead of accessing by calling Setter or Getter methods. KVO is one of the key technologies implemented based on KVC.
Demo:
@interface myPerson : NSObject { NSString*_name; int _age; int _height; int _weight; } @end @interface testViewController :UIViewController @property (nonatomic, retain) myPerson*testPerson; @end - (void)testKVC { testPerson = [[myPerson alloc] init]; NSLog(@"testPerson‘s init height =%@", [testPerson valueForKey:@"height"]); [testPerson setValue:[NSNumber numberWithInt:168]forKey:@"height"]; NSLog(@"testPerson‘s height = %@", [testPerson valueForKey:@"height"]); }
The first piece of code defines a myPerson class. This class has a _height property, but does not provide any getter/setter access methods. At the same time, there is a myPerson object pointer in the testViewController class.
When myPerson is instantiated, it is generally impossible to access the _height property of this object, but we did it through KVC, and the code is the testKVC function.
After running, the print value is:
2015-3-13 11:16:21.970 test[408:c07] testPerson‘s init height = 0
2015-3-13 11:16:21.971 test[408:c07] testPerson‘s height = 168
This means that the _height attribute is indeed read and written.
Common methods of KVC:
- (id)valueForKey:(NSString *)key; -(void)setValue:(id)value forKey:(NSString *)key;
The valueForKey method reads the object's properties based on the value of the key. SetValue:forKey: is to write the object's properties based on the value of the key.
Notice:
(1). The value of the key must be correct. If the spelling is wrong, an exception will occur.
(2). When the value of the key is not defined, valueForUndefinedKey: This method will be called. If you write this method yourself, the value of the key will be called here if it fails.
(3). Because the class keys are nested repeatedly, there is a concept of keyPath. KeyPath is to use . numbers to link keys one by one, so that you can access them according to this path
(4). NSArray/NSSet and others support KVC
2. KVO is the abbreviation of KeyValue Observe, and in Chinese it is key-value observation. This is a typical observer pattern, and the observer is notified when the key value changes. There is a Notification mechanism in iOS, which can also be notified, but this mechanism requires a center. In comparison, KVO is more concise and direct.
The use of KVO is also very simple, just 3 simple steps.
1. Register the attributes of the object that needs to be observed addObserver:forKeyPath:options:context:
2. Implement the observeValueForKeyPath:ofObject:change:context: method. This method will be automatically called when the observed attribute changes.
3. Unregister to observe removeObserver:forKeyPath:context:
Demo:
@interface myPerson : NSObject { NSString *_name; int _age; int _height; int _weight; } @end @interface testViewController : UIViewController @property (nonatomic, retain) myPerson *testPerson; - (IBAction)onBtnTest:(id)sender; @end - (void)testKVO { testPerson = [[myPerson alloc] init]; [testPerson addObserver:self forKeyPath:@"height" options:NSKeyValueObservingOptionNew context:nil]; } - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if ([keyPath isEqualToString:@"height"]) { NSLog(@"Height is changed! new=%@", [change valueForKey:NSKeyValueChangeNewKey]); } else { [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; } } - (IBAction)onBtnTest:(id)sender { int h = [[testPerson valueForKey:@"height"] intValue]; [testPerson setValue:[NSNumber numberWithInt:h+1] forKey:@"height"]; NSLog(@"person height=%@", [testPerson valueForKey:@"height"]); } - (void)dealloc { [testPerson removeObserver:self forKeyPath:@"height" context:nil]; [super dealloc]; }
The first piece of code declares the myPerson class, which contains a _height property. There is a testPerson object pointer in the testViewController.
In the testKVO method, we register the observation of the height attribute of the testPerson object, so that when the height attribute of the testPerson changes, we will be notified. In this method, the NSKeyValueObservingOptionNew parameter is also required to pass the new value in the dictionary.
Rewrite the observeValueForKeyPath:ofObject:change:context: method. The NSDictionary object in this method contains the corresponding value.
It should be emphasized that if the KVO callback is to be called, the attribute must be modified through the KVC method. If other methods of the class are called to modify the attribute, the observer will not be notified.
3. See /eduora_meimei/article/details/44198909 for the usage of NSNotification
the difference:
Advantages of delegate:
1. Very strict grammar. All events that will be heard must be clearly defined in the delegate protocol.
2. If a method in delegate is not implemented, a compilation warning/error will occur
3. The protocol must be defined within the scope of the controller
4. The control flow in an application is traceable and identifiable;
5. In a controller, you can define multiple different protocols, each protocol has different delegates
6. No third-party object requires the maintenance/monitoring of the communication process.
7. Can receive the return value of the called protocol method. This means that delegate can provide feedback to the controller
shortcoming :
1. A lot of code needs to be defined: 1. Delegate property of protocol definition; 3. Implement the delegate method definition in delegate itself
2. When releasing the proxy object, you need to be careful to change delegate to nil. Once the setting fails, the memory crash will occur when calling the method to release the object.
3. There are multiple delegate objects in a controller, and delegate complies with the same protocol, but it is still difficult to tell multiple objects the same event, but it is possible.
Advantages of notification:
1. There is no need to write much code, and the implementation is relatively simple;
2. For a notification issued, multiple objects can react, that is, the 1-to-many method is simple to implement.
Able to pass context object (dictionary), which carries custom information about sending notifications
shortcoming :
1. During the compilation period, the notification will not be checked whether the observer can handle it correctly;
2. When releasing the registered object, you need to cancel the registration in the notification center;
3. It is difficult to track the application work and control process during debugging;
4. A third party is required to manage the connection between the controller and the observer object;
The observer needs to know the notification name and UserInfodictionary keys in advance. If these are not defined in the work interval, then there will be an out-of-sync situation;
6. After the notification is issued, the controller cannot obtain any feedback information from the observer.
Advantages of KVO:
1. Can provide a simple method to achieve synchronization between two objects. For example: synchronization between model and view;
2. Be able to respond to changes in states of objects that are not created by us, that is, internal objects, and do not need to change the implementation of internal objects (SKD objects);
3. Able to provide the latest value and previous value of the observed attribute;
4. Use key paths to observe properties, so you can also observe nested objects;
5. Completed abstraction of the observation object because no additional code is required to allow the observation value to be observed
shortcoming :
1. The properties we observe must be defined using strings. Therefore, there will be no warnings or checks in the compiler;
2. Refactoring the attribute will cause our observation code to no longer be available;
3. The complex "IF" statement requires the object to be observing multiple values. This is because all observation codes point to it in one way;
4. The observer does not need to be removed when the observer is released.
1. The efficiency is definitely higher than that of NSNotification.
The delegate method is more direct than notification. The most typical feature is that the delegate method often needs to pay attention to the return value, that is, the result of the delegate method. For example -windowShouldClose:, you need to care whether it is returned yes or no. Therefore, the delegate method often contains the very vivid word should. That is, it’s like you do my delegate. I will ask you if I want to close the window, would you like? You need to give me an answer and I will decide how to do the next step based on your answer. On the contrary, the biggest feature of notification is that it does not care about the attitude of the recipient. I just let the notice go. Whether you accept it or not is your business, and I don’t care about the result. Therefore, notification often uses the word did, such as NSWindowDidResizeNotification, so after the NSWindow object releases this notification, it will ignore nothing and will not wait for the receiver's reaction.
2. The difference between KVO and NSNotification:
Like delegate, KVO and NSNotification are also communication between classes. Unlike delegate, 1) Both are responsible for issuing notifications, and the rest is ignored, so there is no return value; 2) Delegate is just one-to-one, and these two can be one-to-many. Both have their own characteristics.
Thank you for reading, I hope it can help you. Thank you for your support for this site!