KVO for IOS SDK

Source: Internet
Author: User

KVO for IOS SDK

 

Preface: KVC and KVO are tools that help us navigate the dynamic features of objective C. KVO is based on KVC, so if you are not familiar with KVC, you can refer to my blog. Here I will not repeat KVC.
 
Content of this article

KVO Definition
Typical use cases of KVO.
Manual KVO
What KVO should do

Definition of a KVO

KVO provides a key-value-observing mechanism, that is, you can obtain value changes by listening to the key. Monitors status changes between objects. KVO classes follow the protocol. In fact, any class inherited from NSObject follows this protocol. In Object C, almost all classes are from NSObject.

KVO is generally divided into three steps.

1.1 subscribe to the keypath you want to listen

Functions

- (void)addObserver:(NSObject *)anObserver         forKeyPath:(NSString *)keyPath            options:(NSKeyValueObservingOptions)options            context:(void *)context

Registration notification

Observer: the observer, that is, the subscriber of KVO notifications. Subscription is required
ObserveValueForKeyPath: ofObject: change: context: Method keyPath: Describes the attribute to be observed, relative to the observed attribute. Options: Some attributes of KVO are configured. There are four options. Context: context, which will be passed to the subscribed function to differentiate messages. Therefore, it should be different.

Options content

NSKeyValueObservingOptionNew: change dictionary includes changed values NSKeyValueObservingOptionOld: change dictionary includes changed values NSKeyValueObservingOptionInitial: KVO notification is triggered immediately after registration: whether to notify before the value is changed (this key determines whether to notify the change twice before the change)
1.2 respond to status changes

Every time the monitored keyPath changes, it will be called back in this function.

- (void)observeValueForKeyPath:(NSString *)keyPath                      ofObject:(id)object                        change:(NSDictionary *)change                       context:(void *)context
KeyPath: The monitored keyPath, which is used to distinguish different KVO listeners. Object: the modified object to be observed (the modified value can be obtained through the object) change: the dictionary for saving information changes (old values, new values, etc. may exist) context: context, it is used to differentiate different KVO listeners.
1.3 cancel subscription when appropriate

Two functions are usually used.

- (void)removeObserver:(NSObject *)anObserver            forKeyPath:(NSString *)keyPath- (void)removeObserver:(NSObject *)observer            forKeyPath:(NSString *)keyPath               context:(void *)context

This is usually written during the remove operation, because during the remove operation, you cannot determine whether the remove operation is successful.

    @try {        [object removeObserver:self forKeyPath:keyPath];    }    @catch (NSException *exception) {        NSLog(@%@,exception);    }
Typical use cases of erkvo-synchronization between model and view

Here, you will see a complete KVO example. Like the previous KVC, I wrote a similar demo. Click "random" to randomly change the User's age, and the new and old age will be displayed synchronously on the UI.

The implementation process is as follows:
Defines a User class as a Model.

@interface User : NSObject@property (strong,nonatomic) NSString * name;@property (nonatomic) NSUInteger age;@end

Defines two static variables, one as the keyPath and the other as the context

static  NSString * observename = @age;static void * privateContext = 0;

Then register (subscribe) KVO in viewWillAppear and delete KVO from viewWillDisappear.

-(void)viewWillAppear:(BOOL)animated{    [self.user addObserver:self                forKeyPath:observename                   options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:privateContext];}-(void)viewWillDisappear:(BOOL)animated{    @try {        [self.user removeObserver:self forKeyPath:observename];    }    @catch (NSException *exception) {        NSLog(@%@,exception);    }}

When you click random, the age changes.

- (IBAction)random:(id)sender {    self.user.age = arc4random()%100 +1;}

Then, synchronize the model and view in the function mentioned above.

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{    if (context == privateContext) {        if ([keyPath isEqualToString:observename]) {            NSNumber * old = [change objectForKey:NSKeyValueChangeOldKey];            NSNumber * new = [change objectForKey:NSKeyValueChangeNewKey];            self.lastvalue.text = [NSString stringWithFormat:@%@,old];            self.newvalue.text = [NSString stringWithFormat:@%@,new];        }    }}
Three manual KVO

The implementation of KVO is to automatically implement two functions in the registered keyPath, which are automatically called in Setter.

- (void)willChangeValueForKey:(NSString *)key- (void)didChangeValueForKey:(NSString *)key

Sometimes, we need to implement manual KVO
In this case, you need to disable the automatic generation of KVO notifications and then manually call them. The advantage of manual notifications is that you can flexibly Add the desired judgment conditions. For example

+(BOOL)automaticallyNotifiesObserversOfAge{    return NO;}-(void)setAge:(NSUInteger)age{    if (age < 22) {        return;    }    [self willChangeValueForKey:@age];    _age = age;    [self didChangeValueForKey:@age];}
KVO and Context

Since Context is usually used to distinguish different KVO, the uniqueness of context is very important. Generally, I use static variables in the current. m file.

static void * privateContext = 0;
KVO and thread

The KVO response and the value changes observed by KVO are on one thread. Therefore, do not mix KVO with multithreading in most cases. Unless it can ensure that all observers can handle KVO in a thread safe way

Value of a listener change

Before and after the change

id oldValue = change[NSKeyValueChangeOldKey];id newValue = change[NSKeyValueChangeNewKey];

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.