cool hit counter iosKVO and implementation principles_Intefrankly

iosKVO and implementation principles


summarize KVO, known as KeyValueObserving, is a set of event notification mechanisms provided by Apple. Allows an object to listen for changes to another object's specific properties and receive events when they are changed. The effect on properties only occurs because of the KVO implementation mechanism, and generally objects that inherit from NSObject support KVO by default.

Both KVO and NSNotificationCenter are an implementation of the Observer pattern in iOS. The difference is that the KVO is one-to-one as opposed to one-to-many as opposed to the relationship between the observed and the observer. KVO is non-intrusive to the object being listened to and does not require modification to its internal code to implement listening.

KVO can listen for changes to individual properties, as well as changes to collection objects. The proxy object is obtained through methods such as KVC's mutableArrayValueForKey:, which calls back to the KVO listener when the proxy's internal objects change. The set object contains NSArray and NSSet.

Basic use There are three steps to using KVO. 1.Registering an observer, specifying the properties of the observed object

 [person addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];

2.Implement the following callback methods in the observer

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
{
    NSLog(@"%@",change);
}

3.When the observer does not need to listen

 [person removeObserver:self forKeyPath:@"name"];

Principle of implementation KVO is implemented through isa-swizzling techniques. Create an intermediate class at runtime based on the original class, which is a subclass of the original class, and dynamically modify the isa of the current object to point to the intermediate class. And override the class method to return the Class of the original class.

Test Code

Person *person = [Person new];
person.name = @"old";
NSLog(@"before Class Name:%s",object_getClassName(person));
[person addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
 NSLog(@"after Class Name:%s",object_getClassName(person));

Console Output

2018-09-04 09:59:09.531941+0800 KOVAndKVCDemo[36344:19883033] before Class Name:Person
2018-09-04 09:59:09.532317+0800 KOVAndKVCDemo[36344:19883033] after Class Name:NSKVONotifying_Person

The above principle combined with the code principle can be understood as follows: When observing the object Person, the KVO mechanism dynamically creates a new class named: NSKVONotifying_Person, which inherits from the object Person's home class, and the KVO overrides the setter method of the observed property for NSKVONotifying_Person. The setter method is responsible for notifying all observed objects of the change in the value of the property before and after the original setter method is called.

How to understand that the setter method will be responsible for calling the original setter method before and after, similar to looking at the following code

-(void)setName:(NSString *)name
{
    [self willChangeValueForKey:@"name"];    //KVOAlways call the access method before calling the
    [super name forKey:@"name"]; // Calling the access methods of the parent class
    [self didChangeValueForKey:@"name"];     //KVO After calling the access method always call
}

NSKVONotifying_Person class dissection In this process, the isa pointer of the observed object is modified by the KVO mechanism from pointing to the original Person class to pointing to a newly created subclass of the system, the NSKVONotifying_Person class, to enable listening for changes in the value of the current class attribute.

Subclass setter method dissection KVO's key-value watch notification relies on two NSObject methods:willChangeValueForKey: and didChangevlueForKey:, with 2 separate calls before and after the value is accessed. Before the observed property changes, willChangeValueForKey: is called to notify the system that the property value of the keyPath is about to change; when the change occurs, didChangeValueForKey: is called to notify the system that the property value of the keyPath has changed; afterwards, observeValueForKey:ofObject:change:context: is also called. and overriding the setter method of the observation property is inherited at runtime rather than compile time.

How to implement KVC manually?

 [person willChangeValueForKey:@"name"];
  person.name = @"Alex";
 [person didChangeValueForKey:@"name"];

demo:https://github.com/destinyzhao/KOVAndKVCDemo


Recommended>>
1、How long is a programmers career in China
2、Security issues with urlscheme on PC from CVE20188495
3、Will it take the cake with VR or will it cooperate with VR to share the cake An introduction to 3D reconstruction and applications
4、tower recommendation Have you ever thought about Your approach to data analysis may be outdated
5、adoptedepoll Model Server Connection Manager Implementation

    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号