简述NotificationCenter、KVO、KVC、Del

2021-06-17  本文已影响0人  SunnyWendy

KVO(Key-Value-Observing)

一对多,观察者模式,俗称”键值监听“,可以用于监听某个对象属性值的改变。

当观察一个对象时,runtime会动态创建一个继承自该对象的类,并重写被观察对象的setter方法,重写的setter方法会负责在调用原setter方法前后通知所观察对象值的更改,最后把该对象的isa指针指向这个新建的子类,对象就变成了子类的实例。过程如下:

    1>会调用foundation的NSSetXXXValueAndNotify函数

    2>函数内部实现

     - willChangeValueForKey

    - 父类原来的Setter

    - didChangeValueForKey(内部会触发监听器的监听方法(observeValueForKeyPath:ofObject:change:context:))

如何手动触发KVO

在Setter方法里,手动实现NSObject的两个方法:

- willChangeValueForKey

- didChangeValueForKey

KVC(Key-Value-Coding)

俗称”键值编码“,可以通过一个key来访问属性,常见的API有:

-(void)setValue:(id)value forKey:(NSString *)key;

-(void)setValue:(id)value forKeyPath:(NSString *)keyPath;

-  (id)valueForKey:(NSString *)key;

-  (id)valueForKeyPath:(NSString *)keyPath;

1.setValueForKey原理

1>按照setKey、_setKey顺序查找方法,找到了就传递参数,调用方法

2>如果没找到,就判断(BOOL)AccessInstanceVariablesDirectly函数是否返回Yes,如果返回Yes,就按照_key、_isKey、_key、_iskey顺序查找成员变量,找到了成员变量就直接赋值。找不到成员变量,调用setValue:forUndefinedKey并抛出异常NSUnknownKeyException


2.valueForKey原理

1>调用getter方法,按照getKey、key、isKey、_key顺序查找,如果找到,则直接返回对应的值

2>如果找不到,判断+(BOOL)AccessInstanceVariablesDirectly函数是否返回Yes,如果返回Yes,则访问成员变量_key、_isKey、_key、iskey。找到则返回对应的值,找不到则调用valueForUndefinedKey:抛出异常。


NotificationCenter

多对多,消息的发送者告知接收者事件已经发送或者将要发送,仅此而已,接受者并不能反过来影响发送者的行为。

Delegate

一对一,代理的目的是改变或者传递控制链。允许一个类在某些特定时刻通知到其他类,而不需要获取到那些类的指针。

可以减少框架的复杂度。消息的发送者告知接收者某个事件将要发生,Delegate同意然后发送响应事件,delegate机制使得接收者可以改变发送者的行为。

区别

效率肯定是delegate比NSNotification高

delegate方法比Notification更加直接,需要关注返回值,所以delegate方法往往包含should这个很传神的词。相反的,Notification最大的特色就是不关心结果。所以Notification往往用did这个词汇。

两个模块之间联系不是很紧密,就用Notification传值,例如多线程之间传值

delegate只是一种较为简单的回调,且主要用在一个模块上中,例如底层功能完好,需要把一些值传到上层去,就事先把上层的函数通过delegate传到底层,然后底层调用这个delegate。

上一篇 下一篇

猜你喜欢

热点阅读