first, what is KVO?
Key-value observing, observer pattern
The observer, observing the changes in the properties of the object, will receive a notification when the attribute is changed by the Observer, and can be handled in the callback function accordingly.
What is the role of the two?
Change processing operations can be carried out in the same function, the previous I will change the value of the property every time the next operation, the more cumbersome, modified place is more, now as long as the same function in the operation can be
Use KVO as long as the monitoring is done, more convenient and easy to use, reduce the code logic
third, the use of the scene:
When a control property changes need to do something else, it is more appropriate to use KVO, as long as the property changes, will send a message to the observer, in the callback function to do the appropriate action
Iv. Practical Examples:
a) explanation method:
typedef ns_options (Nsuinteger, nskeyvalueobservingoptions) {nskeyvalueobservingoptionnew=0x01,//the value after the changeNskeyvalueobservingoptionold =0x02,//the value before the changeNskeyvalueobservingoptioninitial ns_enum_available (10_5, 2_0) =0x04,//Addobserving will call Observevalueforkeypath immediately after the change, not until the value changesNskeyvalueobservingoptionprior ns_enum_available (10_5, 2_0) =0x08 //called 2 times. Before the value changes and after the value changes};
nskeyvalueobservingoptionnew = 0x01,//changed value
Nskeyvalueobservingoptionold = 0x02,//value before change
these two use more.
NSObject (nskeyvalueobserving) // once the attribute of the Observer has changed, this method is called for subsequent operations in this method -(void) Observevalueforkeypath: (NSString *) KeyPath Ofobject: (ID)Object Change: (Nsdictionary *) Change context: (void
KeyPath: Is the property of the object being observed, and the string representation
Object: Objects being observed
Change: Property changes the value of the dictionary, via Objectforkey (key for
Foundation_export nsstring *const Nskeyvaluechangekindkey;
Foundation_export nsstring *const Nskeyvaluechangenewkey;
Foundation_export nsstring *const Nskeyvaluechangeoldkey;
Foundation_export nsstring *const Nskeyvaluechangeindexeskey;
Foundation_export nsstring *const nskeyvaluechangenotificationispriorkey ns_available (10_5, 2_0);
Corresponds to the nskeyvalueobservingoptions specified by the addobserving
)
Context: Data to be transmitted (void *: arbitrary pointer type), General (__bridgevoid*) self or nil, the user can also pass other
For example:
- (void) Observevalueforkeypath: (NSString *) KeyPath Ofobject: (ID)ObjectChange: (nsdictionary *) Change context: (void*) Context {if(Context = = (__bridgevoid*) (self) {if([KeyPath Isequaltostring:kkeypathfornavigationitemrightbarbuttonitems]) {//Take valueNsarray *rightbarbuttonitems =[Change Objectforkey:nskeyvaluechangenewkey]; //need to do the operationSelf.navigationItem.rightBarButtonItems =Rightbarbuttonitems; } } Else{[Super Observevalueforkeypath:keypath OfObject:objectchange:changecontext:context]; } }
--------------------------------------------
II) interface method
NSObject (nskeyvalueobserverregistration)- (void) Addobserver: (NSOBJECT *) Observer Forkeypath: (NSString *) keypath options: (nskeyvalueobservingoptions) options Context: (void*) Context; - (void) Removeobserver: (NSOBJECT *) Observer Forkeypath: (NSString *) KeyPath Context: (void*) Context ns_available (10_7, 5_0); - (void) Removeobserver: (NSOBJECT *) Observer Forkeypath: (NSString *) KeyPath; Nsarray (nskeyvalueobserverregistration)- (void) Addobserver: (NSOBJECT *) Observer toobjectsatindexes: (Nsindexset *) Indexes Forkeypath: (NSString *) keypath options: ( nskeyvalueobservingoptions) Options Context: (void*) Context; - (void) Removeobserver: (NSOBJECT *) Observer fromobjectsatindexes: (Nsindexset *) Indexes Forkeypath: (NSString *) keypath Context: (void*) contextns_available (10_7,5_0); - (void) Removeobserver: (NSOBJECT *) Observer fromobjectsatindexes: (Nsindexset *) Indexes Forkeypath: (NSString *) KeyPath; - (void) Addobserver: (NSOBJECT *) Observer Forkeypath: (NSString *) keypath options: (nskeyvalueobservingoptions) options Context: (void*) Context; - (void) Removeobserver: (NSOBJECT *) Observer Forkeypath: (NSString *) KeyPath Context: (void*) Context ns_available (10_7, 5_0); - (void) Removeobserver: (NSOBJECT *) Observer Forkeypath: (NSString *) KeyPath; Nsorderedset (nskeyvalueobserverregistration)- (void) Addobserver: (NSOBJECT *) Observer Forkeypath: (NSString *) keypath options: (nskeyvalueobservingoptions) options Context: (void*) Context; - (void) Removeobserver: (NSOBJECT *) Observer Forkeypath: (NSString *) KeyPath Context: (void*) Context ns_available (10_7, 5_0); - (void) Removeobserver: (NSOBJECT *) Observer Forkeypath: (NSString *) KeyPath; Nsset (nskeyvalueobserverregistration)- (void) Addobserver: (NSOBJECT *) Observer Forkeypath: (NSString *) keypath options: (nskeyvalueobservingoptions) options Context: (void*) Context; - (void) Removeobserver: (NSOBJECT *) Observer Forkeypath: (NSString *) KeyPath Context: (void*) Context ns_available (10_7, 5_0); - (void) Removeobserver: (NSOBJECT *) Observer Forkeypath: (NSString *) KeyPath; NSObject (nskeyvalueobservernotification)//These methods are used in order to manually notify the- (void) Willchangevalueforkey: (NSString *) key; - (void) Didchangevalueforkey: (NSString *) key; - (void) Willchange: (nskeyvaluechange) Changekind valuesatindexes: (nsindexset *) Indexes Forkey: (NSString *) key; - (void) Didchange: (nskeyvaluechange) Changekind valuesatindexes: (nsindexset *) Indexes Forkey: (NSString *) key; - (void) Willchangevalueforkey: (NSString *) key withsetmutation: (nskeyvaluesetmutationkind) Mutationkind usingObjects: ( Nsset *) objects; - (void) Didchangevalueforkey: (NSString *) key withsetmutation: (nskeyvaluesetmutationkind) Mutationkind usingObjects: (NSSet *) objects; NSObject (nskeyvalueobservingcustomization)+ (Nsset *) Keypathsforvaluesaffectingvalueforkey: (NSString *) keyns_available (10_5,2_0); + (BOOL) Automaticallynotifiesobserversforkey: (NSString *) key;
** Addobserver and Removeobserver are going to be paired up.
-----------------------------------------------------------------------
* * Manual notification:
There are two ways to notify the Observer, automatic notification and manual notification. As the name implies, manual notifications need to call Willchangevalueforkey: and Didchangevalueforkey: Methods to notify callers when values change. For simplicity, we generally use automatic notifications.
To use manual notifications, you need to explicitly tell cocoa in the Automaticallynotifiesobserversforkey method which key values to use for manual notifications:
Forexample:
[Self Willchangevalueforkey:@ "frame"= CGRectMake (0,0, (in); [Self Didchangevalueforkey: @" Frame "];
This will call
-(void) Observevalueforkeypath: (NSString *) KeyPath Ofobject: (ID)Object Change: (Nsdictionary * Change context: (void *) context;
// re-Implement the Automaticallynotifiesobserversforkey: Method in the NSObject class and return yes for automatic notification. + (BOOL) Automaticallynotifiesobserversforkey: (nsstring*) key { // When these two values change, using automatic notification of registered observers, the observer needs to implement ObserveValueForKeyPath:ofObject:change:context: Method if ([ Key isequaltostring:@ "frame"]) { return NO ; } return [Super Automaticallynotifiesobserversforkey:key]; } Frame has to be manually notified .
* Manual notification is generally not used, in order to facilitate, are automatically notified, so this part know on the
-----------------------------------------------------------------------
Some of the above interface methods illustrate that Nsobject,nsarray,nsset implements the above methods, so we can observe not only ordinary objects, but also arrays or associative class objects.
It is generally used to observe an attribute of the nsobject to Nsarray to observe the properties of each model in the Nsarray nsset and Nsarray almost, except Nsset is an unordered collection
iOS Development-kvo