美文网首页
iOS NSNotification通知和KVO的使用

iOS NSNotification通知和KVO的使用

作者: 丶天空蓝丶 | 来源:发表于2020-07-08 10:49 被阅读0次
一:KVO: 键值观察

是基于键值编码实现的一种观察者机制,其实现依赖于 Objective-C 强大的 Runtime,当观察某对象 A 时,KVO 机制动态创建一个对象A当前类的子类,并为这个新的子类重写了被观察属性 keyPath 的 setter 方法。setter 方法随后负责通知观察对象属性的改变状况。
Apple 使用了 isa-swizzling 来实现 KVO 。当观察对象A时,KVO机制动态创建一个新的名为:NSKVONotifying_A的新类,该类继承自对象A的本类,且 KVO 为 NSKVONotifying_A重写观察属性的setter 方法,setter 方法会负责在调用原 setter 方法之前和之后,通知所有观察对象属性值的更改情况。

KVO的使用:

1、创建观察对象,在当前类中监测searchString这个字段值是否发生改变

[self addObserver:self forKeyPath:@"searchString" options:NSKeyValueObservingOptionNew context:nil];

2、获取监听,当searchString这个字段值发生改变后,会调用该方法.$\color{red}{r如果searchString为属性,不能使用 _searchString=@"新值" 这种方法改值,需要用 self.searchString=@"新值" 这种方法,否则不会调用下面的方法}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
//    keyPath判断是否是当前监听的值
    if ([keyPath isEqualToString:@"searchString"]) {
//        change[@"new"]获取改变后的值
        _searchStr = change[@"new"];
    }
}

3、移除观察,一般在dealloc方法里面执行

-(void)dealloc {
    [self removeObserver:self forKeyPath:@"searchString"];
}
二:NSNotification通知

是使用观察者模式来实现用于跨层传递消息的机制,传递方式是一对多的

通知 的使用

1、注册监听

//监听searchStringChange字段,如果收到通知调用searchStringChangeNotification方法
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(searchStringChangeNotification:) name:@"searchStringChange" object:nil];

-(void)searchStringChangeNotification:(NSNotification *)notification {
//notification.object为searchStringChange 改变后的值
    _searchStr = notification.object;
}

2、发送通知

//在searchStringChange字段值改变的地方发送通知,这是就会触发searchStringChangeNotification方法
[[NSNotificationCenter defaultCenter] postNotificationName:@"searchStringChange" object:_searchStringChange];

3、移除通知,一般在dealloc方法里面执行

-(void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}
三:使用注意事项

1、如果用通知监听系统的属性,则不需要实现第二步发送通知,如监听键盘事件只需第一步和第三步

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShowNew:) name:UIKeyboardWillShowNotification object:nil];

2、关于移除。现在基本大家测试环境都是iOS13,发现 KVO和通知的第三步移除不写,也没有任何问题。这里说明下,通知的移除是在iOS9.0及以后可以不写了,如果你的项目支持iOS8.0,你也不写通知移除,那么在8.0版本上就会报错;KVO的移除忘了是在iOS11还是iOS12后才可以不写,否则也会报错。

四:同异步

1、通知和KVO都是同步的,即在调起监听后,执行完监听内容才会执行后续代码。

2、KVO实现异步,创建一个异步线程,将值改变放在里面

dispatch_async(dispatch_get_global_queue(0, 0), ^{
   self.searchString = @"值改变";
});

3、通知实现异步,创建一个异步线程,将发送通知放在里面,或者处理事件放在里面

dispatch_async(dispatch_get_global_queue(0, 0), ^{
   [[NSNotificationCenter defaultCenter] postNotificationName:@"searchString" object:@"值改变"];
});
或
-(void)searchStringChangeNotification:(NSNotification *)notification {
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
       sleep(3);
       NSLog(@"%@",notification.object);
    });
}

4、另外,通知的异步可以用NSNotificationQueue,将通知放到通知异步缓冲队列中实现异步操作。将发送通知改成下面代码即可

NSNotification *notification = [NSNotification notificationWithName:@"searchString" object:@"值改变"];
[[NSNotificationQueue defaultQueue] enqueueNotification:notification postingStyle:NSPostASAP];

相关文章

网友评论

      本文标题:iOS NSNotification通知和KVO的使用

      本文链接:https://www.haomeiwen.com/subject/bqrqcktx.html