The NSKeyValueObserving (KVO) informal protocol[非正式协议] defines a mechanism(机制) that allows objects to be notified of changes to the specified properties of other objects.
You can observe any object properties including simple attributes, to-one relationships, and to-many relationships. Observers of to-many relationships are informed of the type of change made — as well as which objects are involved in the change.
NSObject provides an implementation of the NSKeyValueObserving protocol that provides an automatic observing capability for all objects. You can further refine notifications by disabling automatic observer notifications and implementing manual notifications using the methods in this protocol.
NOTE----Key-value observing is not available for Java applications.
Change notification
- observeValueForKeyPath:ofObject:change:context:
This message is sent to the receiver when the value at the specified key path relative to the given object has changed.
DeclarationSWIFT
func observeValueForKeyPath(_ keyPath: String?,
ofObject object: AnyObject?,
change change: [String : AnyObject]?,
context context: UnsafeMutablePointer)
OBJECTIVE-C
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary*)change
context:(void *)context
Parameters
keyPath The key path, relative to object, to the value that has changed.
object The source object of the key path keyPath.
change A dictionary that describes the changes that have been made to the value of the property at the key path keyPath relative to object. Entries are described in Change Dictionary Keys.
context The value that was provided when the receiver was registered to receive key-value observation notifications.
Discussion
The receiver must be registered as an observer for the specified keyPath and object.
Registering for observation
- addObserver:forKeyPath:options:context:
Registers anObserver to receive KVO notifications for the specified key-path relative to the receiver.
DeclarationSWIFT
func addObserver(_ observer: NSObject,
forKeyPath keyPath: String,
options options: NSKeyValueObservingOptions,
context context: UnsafeMutablePointer)
OBJECTIVE-C
- (void)addObserver:(NSObject *)anObserver
forKeyPath:(NSString *)keyPath
options:(NSKeyValueObservingOptions)options
context:(void *)context
Parameters
anObserver The object to register for KVO notifications. The observer must implement the key-value observing method observeValueForKeyPath:ofObject:change:context:.
keyPath The key path, relative to the receiver, of the property to observe. This value must not be nil.
options A combination of the NSKeyValueObservingOptions values that specifies what is included in observation notifications. For possible values, see NSKeyValueObservingOptions.
context Arbitrary data that is passed to anObserver in observeValueForKeyPath:ofObject:change:context:.
Discussion
Neither the receiver, nor anObserver, are retained. An object that calls this method must also call either the removeObserver:forKeyPath: or removeObserver:forKeyPath:context: method when participating in KVO.
- removeObserver:forKeyPath:
Stops a given object from receiving change notifications for the property specified by a given key-path relative to the receiver.
Declaration
SWIFT
func removeObserver(_ observer: NSObject,
forKeyPath keyPath: String)
OBJECTIVE-C
- (void)removeObserver:(NSObject *)anObserver
forKeyPath:(NSString *)keyPath
Parameters
anObserver The object to remove as an observer.
keyPath A key-path, relative to the receiver, for which anObserver is registered to receive KVO change notifications.
Discussion
It is an error to call removeObserver:forKeyPath: if the object has not been registered as an observer.
Be sure to invoke this method (or removeObserver:forKeyPath:context:) before any object specified in addObserver:forKeyPath:options:context: is deallocated.
- removeObserver:forKeyPath:context:
Stops a given object from receiving change notifications for the property specified by a given key-path relative to the receiver and a context.
DeclarationSWIFT
func removeObserver(_ observer: NSObject,
forKeyPath keyPath: String,
context context: UnsafeMutablePointer)
OBJECTIVE-C
- (void)removeObserver:(NSObject *)observer
forKeyPath:(NSString *)keyPath
context:(void *)context
Parameters
observer The object to remove as an observer.
keyPath A key-path, relative to the receiver, for which anObserver is registered to receive KVO change notifications.
context Arbitrary data that more specifically identifies the observer to be removed.
Discussion
Examining the value in context you are able to determine precisely which addObserver:forKeyPath:options:context: invocation was used to create the observation relationship(观察关系,监听关系). When the same observer is registered for the same key-path multiple times, but with different context pointers, an application can determine specifically which object to stop observing. It is an error to call removeObserver:forKeyPath:context: if the object has not been registered as an observer.
Be sure to invoke this method (or removeObserver:forKeyPath:) before any object specified in addObserver:forKeyPath:options:context: is deallocated.
Notifying observers of changes(通知 观察者 的变化)
- willChangeValueForKey:
Invoked(唤起) to inform(通知) the receiver that the value of a given property is about to change.
Declaration
SWIFT
func willChangeValueForKey(_ key: String)
OBJECTIVE-C
- (void)willChangeValueForKey:(NSString *)key
Parameters
key The name of the property that will change.
Discussion
You should invoke this method when implementing key-value observer compliance manually.
The change type of this method is NSKeyValueChangeSetting.
IMPORTANT
After the values have been changed, a corresponding didChangeValueForKey: must be invoked with the same parameter.
Special Considerations
You should not override this method in subclasses.
See Also
– didChangeValueForKey:
– willChange:valuesAtIndexes:forKey:
- didChangeValueForKey:
Invoked to inform the receiver that the value of a given property has changed.
Declaration
SWIFT
func didChangeValueForKey(_ key: String)
OBJECTIVE-C
- (void)didChangeValueForKey:(NSString *)key
Parameters
key The name of the property that changed.
Discussion
You should invoke this method when implementing key-value observer compliance manually.
Special Considerations
You should not override this method in subclasses.
See Also
– willChangeValueForKey:
– didChange:valuesAtIndexes:forKey:
- willChange:valuesAtIndexes:forKey:
Invoked to inform the receiver that the specified change is about to be executed at given indexes for a specified ordered to-many relationship.
Declaration
SWIFT
func willChange(_ changeKind: NSKeyValueChange,
valuesAtIndexes indexes: NSIndexSet,
forKey key: String)
OBJECTIVE-C
- (void)willChange:(NSKeyValueChange)change
valuesAtIndexes:(NSIndexSet *)indexes
forKey:(NSString *)key
Parameters
change The type of change that is about to be made.
indexes The indexes of the to-many relationship that will be affected by the change.
key The name of a property that is an ordered to-many relationship.
Discussion
You should invoke this method when implementing key-value-observing compliance manually.
IMPORTANT
After the values have been changed, a corresponding didChange:valuesAtIndexes:forKey: must be invoked with the same parameters.
Special Considerations
You should not override this method in subclasses.
See Also
– didChange:valuesAtIndexes:forKey:
– willChangeValueForKey:
- didChange:valuesAtIndexes:forKey:
Invoked to inform the receiver that the specified change has occurred on the indexes for a specified ordered to-many relationship.
Declaration
SWIFT
func didChange(_ changeKind: NSKeyValueChange,
valuesAtIndexes indexes: NSIndexSet,
forKey key: String)
OBJECTIVE-C
- (void)didChange:(NSKeyValueChange)change
valuesAtIndexes:(NSIndexSet *)indexes
forKey:(NSString *)key
Parameters
change The type of change that was made.
indexes The indexes of the to-many relationship that were affected by the change.
key The name of a property that is an ordered to-many relationship.
Discussion
You should invoke this method when implementing key-value-observing compliance manually.
Special Considerations
You should not override this method in subclasses.
See Also
– willChange:valuesAtIndexes:forKey:
– didChangeValueForKey:
- willChangeValueForKey:withSetMutation:usingObjects:
Invoked to inform the receiver that the specified change is about to be made to a specified unordered to-many relationship.
DeclarationSWIFT
func willChangeValueForKey(_ key: String,
withSetMutation mutationKind: NSKeyValueSetMutationKind, usingObjects objects: Set)
OBJECTIVE-C
- (void)willChangeValueForKey:(NSString *)key
withSetMutation:(NSKeyValueSetMutationKind)mutationKind
usingObjects:(NSSet *)objects
Parameters
key The name of a property that is an unordered to-many relationship
mutationKind The type of change that will be made.
objects The objects that are involved in the change (see NSKeyValueSetMutationKind).
Discussion
You invoke this method when implementing key-value observer compliance manually.
IMPORTANT
After the values have been changed, a corresponding didChangeValueForKey:withSetMutation:usingObjects: must be invoked with the same parameters.
Special Considerations
You should not override this method in subclasses.
See Also
– didChangeValueForKey:withSetMutation:usingObjects:
- didChangeValueForKey:withSetMutation:usingObjects:
Invoked to inform the receiver that the specified change was made to a specified unordered to-many relationship.
DeclarationSWIFT
func didChangeValueForKey(_ key: String,
withSetMutation mutationKind: NSKeyValueSetMutationKind, usingObjects objects: Set)
OBJECTIVE-C
- (void)didChangeValueForKey:(NSString *)key
withSetMutation:(NSKeyValueSetMutationKind)mutationKind
usingObjects:(NSSet *)objects
Parameters
key The name of a property that is an unordered to-many relationship
mutationKind The type of change that was made.
objects The objects that were involved in the change (see NSKeyValueSetMutationKind).
Discussion
You invoke this method when implementing key-value observer compliance manually.
Special Considerations
You should not override this method in subclasses.
Observing customization----自定义观察机制
+ automaticallyNotifiesObserversForKey:
Returns a Boolean value that indicates whether the receiver supports automatic key-value observation for the given key.
DeclarationSWIFT
class func automaticallyNotifiesObserversForKey(_ key: String) -> Bool
OBJECTIVE-C
+ (BOOL)automaticallyNotifiesObserversForKey:(NSString *)keyReturn ValueYES if the key-value observing machinery should automatically invoke willChangeValueForKey:/didChangeValueForKey: and willChange:valuesAtIndexes:forKey:/didChange:valuesAtIndexes:forKey: whenever instances of the class receive key-value coding messages for the key, or mutating key-value-coding-compliant methods for the key are invoked; otherwise NO.
Discussion
The default implementation returns YES. Starting in OS X 10.5, the default implementation of this method searches the receiving class for a method whose name matches the pattern
+automaticallyNotifiesObserversOf, and returns the result of invoking that method if it is found. Any found methods must return BOOL. If no such method is found YES is returned.
+ keyPathsForValuesAffectingValueForKey:
Returns a set of key paths for properties whose values affect the value of the specified key.
DeclarationSWIFT
class func keyPathsForValuesAffectingValueForKey(_ key: String) -> Set
OBJECTIVE-C
+ (NSSet*)keyPathsForValuesAffectingValueForKey:(NSString *)keyParameterskey
The key whose value is affected by the key paths.Return ValueDiscussionWhen an observer for the key is registered with an instance of the receiving class, key-value observing itself automatically observes all of the key paths for the same instance, and sends change notifications for the key to the observer when the value for any of those key paths changes.The default implementation of this method searches the receiving class for a method whose name matches the pattern +keyPathsForValuesAffecting, and returns the result of invoking that method if it is found. Any such method must return an NSSet. If no such method is found, an NSSet that is computed from information provided by previous invocations of the now-deprecated setKeys:triggerChangeNotificationsForDependentKey: method is returned, for backward binary compatibility.You can override this method when the getter method of one of your properties computes a value to return using the values of other properties, including those that are located by key paths. Your override should typically invoke super and return a set that includes any members in the set that result from doing that (so as not to interfere with overrides of this method in superclasses).
NOTE
You must not override this method when you add a computed property to an existing class using a category, overriding methods in categories is unsupported. In that case, implement a matching +keyPathsForValuesAffectingto take advantage of this mechanism.
Availability
Available in iOS 2.0 and later.
- observationInfo
Sets the observation info for the receiver.
DeclarationSWIFT
var observationInfo: UnsafeMutablePointer
OBJECTIVE-C
@property void *observationInfo
Parameters
observationInfo The observation info for the receiver.
Discussion
The observationInfo is a pointer that identifies information about all of the observers that are registered with the receiver. The default implementation of this method stores observationInfo in a global dictionary keyed by the receiver’s pointers.
For improved performance, this method and observationInfo can be overridden to store the opaque data pointer in an instance variable. Classes that override this method must not attempt to send Objective-C messages to observationInfo, including retain and release.