博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
KVO
阅读量:5122 次
发布时间:2019-06-13

本文共 2246 字,大约阅读时间需要 7 分钟。

利用键值观察,你可以自动观察其他对象的变化。因此,当一个对象改变状态时你就会得到通知,比如用户通过应用中的设置面板g改变了设置时。通过键值观察,利用该设置的窗体和其他对象在用户改变设置时,都可以自动得到通知。你不需要手动告诉其他对象进行更新。他们会自动收到新值并执行适当的操作。这是极其强大的。设置是该技术最强大的应用之一。此外,Cocoa框架中的核心数据和其他技术也利用了键值观察实现了一些奇妙的功能。

要使用键值观察,被观察的对象必须对所观察的特性使用符合KVC标准的存取器方法。第二,想要观察变化的对象,也就是观察者,必须实现一个接收通知的特殊方法。该方法是-observeValue:forkeyPath:ofObject:change:context:。该方法在值变化时被调用并可以配置成同时接收新值和原值以及其他自定义的信息。

最后,观察者通过调用-addObserver:forKeyPath:options:context:方法针对被观察对象进行注册。调用该方法,告诉对象要观察的KVC键值路径以及希望看到的变化,并提供一个在收到变化通知时可以传回的上下文对象。

但观察者完成这些配置后,键路径指定的属性的任何变化都可以自动调用观察者的回调方法。在观察者完成被观察对象的观察后,必须将自己移除。如果没有做到这一点并且观察者之后就释放了,将来向该观察者发送消息通知时可能会导致应用崩溃。

 

注册成为观察者

针对于要观察的对象调用-addObserver:forKeyPath:options:context:方法。observer参数通常是self这是在被观察值变化时收到通知的对象。键路径参数指定想要观察的特性的键路径。options参数指定一些标记来告诉KVO你希望变化如何传给你。这些值可以通过|操作符进行或操作。

NSKeyValueObservingOptionNew 作为变更信息的一部分发送新值

NSKeyValueObservingOptionOld   作为变更信息的一部分发送旧值

NSKeyValueObservingOptionInitial   在观察者注册时发送一个初始更新

NSKeyValueObservingOptionPrior   在更变前后分别发送更变,而不只在更变后发送一次

上下文参数是一个在KVO系统中无变更传递的void*参数,并且会在有变更通知时传回给你的对象。本质上,就KVO而言,该参数是不透明的数据块,并且完全是和实现相关的。任何从此传人参数的都会无变更传递的。(不要将一些存储在栈上的值传递给该参数。跟垃圾回收有关系)

 

定义KVO的回调

使用KVO第二步是回调,-observerValue:forKeyPath:ofObject:change:context:。该方法自动传入一个对象参数,告诉你哪个对象想你发送了通知。通知对键值路径的传入值使用-isEquals方法,你可以准确地确定对象的什么特性发生了改变。Key参数仅仅是一个字符串,和对KVC使用时一样。因此,你可以使用NSString方法-isEqualToString:来确定该通知所对应的键值路径。实际变化通过change参数传递给你。该参数是字典对象,包含了注册观察者时所请求的变化信息相关的键和值。

NSKeyValueChangeKindKey 指定变化类型的NSNumber

NSKeyValueChangeNewKey 新值

NSKeyValueChangeOldKey 原值

NSKeyValueChangeIndexeskey 如果NSKeyValueChangeKindKey是NSKeyValueChangeInsertion、 NSKeyValueChangeRemoval、NSKeyValueChangeReplacement 之一,该值就包含变化值的索引

NSKeyValueChangeNotificationIsPriorKey 和NSKeyValueChangeOptionPrior 结合使用来表示这是 之前的通知

 

 

 

NSKeyValueChangeKindKey指定了接收到变化类型

NSKeyValueChangeSetting 指定该值被设置

NSKeyValueChangeInsertion 指定这些值插入到集合或者一对多的关系

NSKeyValueChangeRemoval 指定这些值在一对多的关系中被移除

NSKeyValueChangeReplacement 指定这些值在一对多的关系中被代替

 

 

移除观察者

在结束对一个对象变化的观察后,需要移除观察者,如果不这样,可能会崩溃。

调用的方法就是-removeObserver:forKeyPath:,观察者作为第一个参数,观察的路径是第二个参数。

 

 

 

实现手动通知

所有的这些通知都是自动发生的,如果想一次性进行很多更变,可能将想要的这些变化打包一起发送。这种情况只能用手动通知。

必须重写+automaticallyNotifiesObserversForKey:

 

如果想手动通知所发生的变化,必须在变化之前调用方法-willChangeValueForKey:然后在变化之后调用方法-didChangeValueForKey:

 

 

 

(来自:学好Objective -C)

 

转载于:https://www.cnblogs.com/teng7922/p/4421980.html

你可能感兴趣的文章
性能优化个人认识小结
查看>>
php 用户注册表设计,用户ID类型GUID
查看>>
ThinkPHP跨控制器调用方法
查看>>
dt.jar设计时rt.jar运行时
查看>>
JS类、对象、方法、prototype、_proto_
查看>>
判断模式分解是否具有无损链接性
查看>>
三十分钟学习STL【转载】
查看>>
stderr 和stdout
查看>>
Silverlight:xap包(或本地缓存)下载版本更新的解决思路
查看>>
团队绩效考核表
查看>>
Django model字段类型清单
查看>>
MAPZONE GIS SDK接入Openlayers3之四——高级标注效果实现
查看>>
selenium RC环境配置
查看>>
iOS ipv6 被拒
查看>>
dubbo源代码编译打包错误解决
查看>>
[译]GotW #3: Using the Standard Library (or, Temporaries Revisited)
查看>>
期货小鳄鱼:市场交易里,做多做空本无所谓对错
查看>>
HTML的语法
查看>>
vue从入门到进阶:简介(一)
查看>>
swift 数据存储
查看>>