KVO原理

原理:

刨根问底KVO原理-CSDN博客

面试题:

不想让别人通过 Key-Value Observing (KVO) 监听某个属性 

 在 Objective-C 中,如果你不想让别人通过 Key-Value Observing (KVO) 监听某个属性,你可以采取以下几种方法来阻止或者隐藏属性的 KVO 功能:

  1. 重写自动通知的方法
    KVO 通知依赖于 NSObject 的 willChangeValueForKey: 和 didChangeValueForKey: 方法。你可以重写这些方法,并且不调用它们的 super 实现,这样就不会发送 KVO 通知了。例如:

    - (void)setSomeProperty:(NSString *)someProperty {
        // 不调用 willChangeValueForKey 和 didChangeValueForKey,阻止 KVO
        _someProperty = someProperty;
    }
    
  2. 返回 NO 于自动 KVO 的类方法:
    你可以重写 + (BOOL)automaticallyNotifiesObserversForKey: 类方法,对指定的 key 返回 NO,这样就不会为这个 key 自动生成 KVO 通知了:

    + (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key {
        if ([key isEqualToString:@"someProperty"]) {
            return NO;
        }
        return [super automaticallyNotifiesObserversForKey:key];
    }
    
  3. 使用私有属性
    如果你不想让外部对象知道某个属性的存在,可以将其声明在类的实现文件中的类扩展(Extension)里。这样,这个属性就不会暴露在类的公共头文件中,外部对象也就不知道这个属性的存在,从而无法对其进行 KVO。

    @interface MyClass ()
    @property (nonatomic, strong) NSString *privateProperty;
    @end
    
  4. 手动管理 KVO
    如果需要更精细的控制,可以手动管理 KVO 通知。这意味着在属性变化时手动调用 willChangeValueForKey: 和 didChangeValueForKey:,而在不想发送通知的时候则不调用。

  5. 文档说明
    在某些情况下,可能无法从技术上阻止 KVO,或者这样做可能导致其他问题。此时,可以在类的文档中明确指出某些属性不支持 KVO,并且不保证对这些属性的 KVO 监听会有任何效果。

需要注意的是,阻止 KVO 可能会违反类的设计意图,并可能导致使用该类的其他代码出现问题。因此,除非有充分的理由,否则通常不建议禁用 KVO。如果你的类是为其他开发者使用的 API 的一部分,最好在设计时就考虑到这一点,并在文档中明确指出哪些属性支持 KVO,哪些不支持。

KVO(Key-Value Observing)是iOS开发中的一种观察者模式,用于观察对象的属性值的变化。通过KVO,可以在属性值变化时自动收到通知,并执行相应的操作。

使用KVO需要注意以下问题:

  1. 添加和移除观察者:在使用KVO之前,需要使用addObserver:forKeyPath:options:context:方法添加观察者,并在不需要观察时使用removeObserver:forKeyPath:方法手动移除观察者。注意要在合适的时机添加和移除观察者,避免引起内存泄漏或观察无效的对象。

  2. 观察的属性必须是Objective-C对象:KVO只能用于观察Objective-C对象的属性,而不能用于基本数据类型(如int、float等)和结构体。

  3. 重写属性的存取方法:如果要观察的属性没有提供自动生成的存取方法,需要手动重写属性的存取方法,并在其中发送KVO通知。在属性的setter方法中,需要调用willChangeValueForKey:方法和didChangeValueForKey:方法,分别在修改属性值之前和之后发送通知。

  4. 观察属性的线程安全:KVO通知是在默认的RunLoop中发送的,因此,如果在多线程环境中观察属性的变化,需要保证线程安全。可以通过在合适的地方使用@synchronized或其他线程同步机制来避免竞争条件。

  5. KVO通知的顺序问题:多个属性的变化可能会同时触发多个KVO通知,但是不能保证通知的触发顺序。如果有多个属性的变化顺序有依赖关系,需要在观察者中进行处理,确保按照正确的顺序处理属性的变化。

  6. 键路径(Key Path)的使用:可以使用键路径来观察对象的嵌套属性。键路径是由多个属性名连接而成的字符串,用于表示对象的属性路径。在注册观察者时,需要使用正确的键路径来指定观察的属性。

以上是使用KVO需要注意的一些问题,正确地使用KVO可以方便地实现对属性变化的观察和响应。

7.KVO,直接给成员变量赋值会不会触发kvo?

在 Objective-C 中,直接给成员变量赋值不会触发 KVO(Key-Value Observing)。KVO 是通过监听对象属性值的变化来实现的,如果直接通过成员变量赋值,不会触发 KVO。

KVO 是基于 Objective-C 的动态特性实现的,当你使用属性的 setter 方法来改变属性的值时,KVO 机制会自动发送通知。但是,直接访问实例变量(成员变量)绕过了属性的 setter 方法,因此不会触发 KVO。

因此,如果你希望在属性值变化时触发 KVO,应该通过属性的 setter 方法来设置属性的新值,而不是直接访问成员变量。

        8.能对私有变量KVO吗?能对私有变量的属性KVO吗?

在 Objective-C 中,KVO 通常是基于属性进行的,而不是基于实例变量(私有变量)。正常情况下,KVO 只能用于公开的属性,因为 KVO 是基于属性观察的。

然而,虽然不能直接对私有变量进行 KVO,但是你仍然可以使用 KVC(Key-Value Coding)来间接地观察私有变量的变化。KVC 允许你通过键路径访问对象的属性,包括私有属性。

具体做法是通过 KVC 提供的方法来访问私有属性,然后对这些属性进行 KVO 观察。这样可以绕过直接对私有变量进行 KVO,但是需要小心使用,因为直接操作私有变量可能会导致不可预料的行为,并且可能违反了封装的原则。

需要注意的是,对私有变量进行 KVO 并不是一种推荐的做法。通常建议尽量使用公开的 API 来实现 KVO,以确保代码的稳定性和可维护性。

在 Objective-C 中,即使是私有属性,也是可以使用 KVO(Key-Value Observing)的。虽然私有属性通常不直接暴露给外部,但是你仍然可以使用 KVO 来观察这些属性的变化。

当你使用 KVO 监听私有属性时,你需要确保在进行观察之前,调用- (void)willChangeValueForKey:(NSString *)key- (void)didChangeValueForKey:(NSString *)key方法。这样可以手动触发 KVO 通知,通知系统属性值的变化。

例如,假设有一个名为privateProperty的私有属性,你可以这样进行 KVO 观察:

// 添加观察者
[self addObserver:self forKeyPath:@"privateProperty" options:NSKeyValueObservingOptionNew context:NULL];

// 在属性值改变之前调用
[self willChangeValueForKey:@"privateProperty"];
// 设置新值
_privateProperty = newValue;
// 在属性值改变之后调用
[self didChangeValueForKey:@"privateProperty"];

需要注意的是,虽然可以对私有属性进行 KVO,但是在实际应用中,应该慎重考虑是否有必要对私有属性进行 KVO。因为私有属性的改变可能会在不同的版本中发生变化,这样可能导致 KVO 监听不再有效,从而影响代码的稳定性。

  • 20
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Flutter和Objective-C(简称OC)都是开发移动应用程序的技术,但它们在很多方面有着不同的特点。 首先,Flutter是一种跨平台的移动应用开发框架,由谷歌开发。它使用Dart语言编写,具有热重载、响应式UI框架和丰富的UI组件等特点。Flutter的一大优势是可以同时在iOS和Android平台上开发应用程序,并且拥有高性能和良好的用户体验。Flutter也支持使用原生代码进行集成,因此可以很好地与Objective-C进行交互。 Objective-C是一种面向对象的编程语言,主要用于iOS和macOS平台的应用程序开发。Objective-C采用了一种称为KVO(Key-Value Observing)的机制,允许对象对属性和值的变化进行观察和响应。通过注册观察者,当被观察对象的属性发生变化时,观察者可以接收到通知并执行相应的操作。KVO是一种非常强大的工具,可以用于实现对象之间的数据绑定和通信。 在使用Flutter开发应用时,可以与Objective-C进行集成,并利用Objective-C提供的KVO机制来实现对Flutter应用内部变量的监视和响应。这可以通过在Flutter与Objective-C之间建立桥接来实现,从而达到在Flutter应用中使用KVO的目的。 总的来说,Flutter和Objective-C KVO是两种不同的技术,Flutter是一个跨平台的移动应用开发框架,而Objective-C KVO是一种可以用于观察和响应对象属性变化的机制。在合适的场景下,可以通过Flutter与Objective-C进行集成,从而利用KVO机制来实现对Flutter应用内部变量的监视和响应。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值