iOS KVO和KVC介绍

iOS KVO和KVC介绍

KVO和KVC都是基于对NSObject的扩展来实现的,所有继承于NSObject的子类都能使用KVO和KVC。

用来测试的model:

@interface User : NSObject
@property (assign, nonatomic) NSInteger uid;
@property (copy, nonatomic) NSString *name;
@property (assign, nonatomic) Float64 height;
@property (strong, nonatomic) User *subUser;
@end

KVO

KVO全称Key Value Observing。使用KVO可以监听对象的某个key或者keyPath它的value值的变化。

  • key可以视为对象的属性
  • keyPath是针对对象的属性也是一个对象的情况,使用"object.property"的形式来访问属性对象(object)的属性(property)
  • 对象的属性修改之后马上就会同步调用观察者的observeValueForKeyPath:ofObject:change:context:方法。等该方法执行完毕之后才会返回修改的位置执行之后的逻辑。
  • 在添加观察者的时候需要添加option:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew,这样在回调observeValueForKeyPath的时候就可以通过change字典:change[“new”]和change[“old”]来获取新旧值。

示例:

{
    User *user = [User new];
    user.name = @"an old name";
    [user addObserver:self forKeyPath:NSStringFromSelector(@selector(name)) options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:nil];

    NSLog(@"准备修改user.name");
    user.name = @"a new name";
    NSLog(@"修改user.name完成");
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    NSLog(@"观察到user.name发生变化, old:%@, new:%@", change[@"old"], change[@"new"]);
    NSLog(@"user.class: %@", [NSString stringWithUTF8String: class_getName([object class])]);
}

运行结果:

2019-07-19 14:22:35.595521+0800 MakeStrong[4975:90955] 准备修改user.name
2019-07-19 14:22:35.595731+0800 MakeStrong[4975:90955] 观察到user.name发生变化, old:an old name, new:a new name
2019-07-19 14:22:35.595817+0800 MakeStrong[4975:90955] user.class: User
2019-07-19 14:22:35.595920+0800 MakeStrong[4975:90955] 修改user.name完成

上述代码我们使用了NSStringFromSelector(@selector(name))来 获取属性名,是为了避免硬编码。

KVC

KVC全称Key Value Coding。使用KVC可以不需要调用getter跟setter就可以获取和修改对象的属性值。KVC同样也是有key和keyPath的概念。

修改value的方法:
在这里插入图片描述

获取value的方法:
在这里插入图片描述

示例:

    //KVC
    User *user = [User new];
    user.subUser = [User new]; //首先需要实例化subUser,否则下面的setValue会无效
    [user setValue:@"momingqi" forKeyPath:@"subUser.name"]; //修改user.subUser.name属性
    NSString *subUserName = [user valueForKeyPath:@"subUser.name"];
    NSLog(@"%@", subUserName);

KVC中还有两个特殊的方法:
- (void)setValue:(id)value forUndefinedKey:(NSString *)key;

  • 这个方法需要NSObject的子类重写,否则会抛出异常NSUndefinedKeyException。
  • (id)valueForUndefinedKey:(NSString *)key;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值