This is the 11th day of my participation in the August More Text Challenge. For details, see:August is more challenging
Hi 👋
- Wechat: RyukieW
- 📦 Technical article archive
- 🐙 making
My personal project | Mine Elic endless sky ladder | Dream of books |
---|---|---|
type | The game | financial |
AppStore | Elic | Umemi |
preface
KVO is often used in development, but there are hidden corners that are often overlooked, and this article will explore some of those corners.
⚠️ Important Notes
Important: In order to understand key-value observing, you must first understand key-value coding.
Important: In order to understand KVO, you must first understand KVC. Recommended reading: IOS-KVC detailed explanation
A, the Options
It affects the contents of the change dictionary provided in the notification and how the notification is generated.
NSKeyValueObservingOptionOld
Change the previous value
NSKeyValueObservingOptionNew
Receive the new value
NSKeyValueObservingOptionInitial
Your instructions immediately change notification that is sent by the observation object using option NSKeyValueObservingOptionInitial (in addObserver: forKeyPath: options: context: before returns). You can use this additional one-time notification to get the initial value.
NSKeyValueObservingOptionPrior
You can include option NSKeyValueObservingOptionPrior instructions were observed before the property change notifications (in addition to change usually notice).
Change dictionary by including key NSKeyValueChangeNotificationIsPriorKey and contains YES NSNumber values change notification in advance.
Multiple can be received through a bitwise enumeration of these options
Second, the Context
[tool.ryuk addObserver:tool forKeyPath:@"name" options:NSKeyValueObservingOptionNew context:NULL];
Copy the code
In normal use, we usually pass NULL but what is it really doing?
AddObserver: forKeyPath: options: context: in the message context pointer can contain any data, these data will be passed back to the observer in the corresponding change notification. You can specify NULL and rely entirely on the key path string to determine the source of the change notification, but this approach can cause an object’s parent class to have problems observing the same key path for different reasons.
A more secure and extensible approach is to use Context to ensure that the notifications you receive are sent to your observers and not to the superclass.
The address of the uniquely named static variable in the class is a nice Context. Contexts selected in a similar manner in a parent or child class are unlikely to overlap. You can select a Context for the entire class and rely on the critical path string in the notification message to determine what has changed.
Alternatively, you can create a different Context for each observed key path, bypassing string comparisons altogether and improving notification parsing.
createContext
Pointer to the
static void *PersonAccountBalanceContext = &PersonAccountBalanceContext;
static void *PersonAccountInterestRateContext = &PersonAccountInterestRateContext;
Copy the code
Registered observer
- (void)registerAsObserverForAccount:(Account*)account {
[account addObserver:self
forKeyPath:@"balance"
options:(NSKeyValueObservingOptionNew |
NSKeyValueObservingOptionOld)
context:PersonAccountBalanceContext];
[account addObserver:self
forKeyPath:@"interestRate"
options:(NSKeyValueObservingOptionNew |
NSKeyValueObservingOptionOld)
context:PersonAccountInterestRateContext];
}
Copy the code
Observation of mutable arrays
KVO relative to a mutable array would probably write something like this. But obviously it doesn’t work. In order to understand KVO, you must first understand KVC.
The API needs to be adjusted in order to enable changes within the mutable Collection to be heard
mutableArrayValueForKey:
andmutableArrayValueForKeyPath:
- return
NSMutableArray
- return
mutableSetValueForKey:
andmutableSetValueForKeyPath:
- return
NSMutableSet
- return
mutableOrderedSetValueForKey:
andmutableOrderedSetValueForKeyPath:
- return
NSMutableOrderedSet
- return
Four, KVO switch control
If you write a library and you don’t want some of the properties inside to be listened on. Is there any way to stop it?
+ (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key;
Copy the code
The system provides the above method, which returns YES by default, meaning that all properties can be listened on. You can return NO if you don’t want some or all of them to be listened on.
4.1 Prohibit All
There is no notification to trigger the change
4.2 Partial Prohibition
The name notification did not trigger, the books notification did.
4.3 Manually Sending a Notification after being Disabled
Although automaticallyNotifiesObserversForKey banned notice, but can still listen to normal after manually triggered
reference
- Key-Value Observing Programming Guide
- Key-Value Coding Programming Guide