iOS -KVO和KVC的使用

KVO和KVC可以说是好几年的技术了,之前一直用通知、代理以及Block,发现这几个已经够用了,就没有去仔细的去研究。当然了开发过程中也偶尔用到,那是在遇到困难问题的时候,在网上找的方法里面带有的,在第三方库里面也经常也到,今天有时间就稍微研究下,其实非常简单的,很容易入手应用。

一、KVC KVO
KVC(Key Value Coding)键值编码,是可以通过对象属性名称(Key)直接给属性值(Value)编码(Coding),这里的“编码”可以理解为“赋值”。这样可以免去我们调用getter和setter方法,从而简化我们的代码。也可以用来修改系统控件内部属性。

KVO : (Key Value Observer) 键值观察者,是观察者设计模式的一种具体实现(C层和M层的通信)。KVO触发机制:一个对象(观察者),检测另一个对象(被观察者)的某属性是否发生变化,若被监测的属性发生了更改,会触发观察者的一个方法(方法名固定,类似代理方法)

类:Teacher
.h

@interface Teacher : NSObject

@property (nonatomic , copy) NSString * name; ///< 姓名
@property (nonatomic , strong) Student *student; ///< 学生

@end

.m

@interface Teacher ()
{
    NSString * _height;
}
@property (nonatomic , copy) NSString *age;

@end

类Student
.h

@interface Student : NSObject

@property (nonatomic , copy) NSString * weight; ///< 学生体重

@end

.m

@implementation Student
@end

类ViewController
.m

@interface ViewController ()
@property (nonatomic , strong) Teacher *teacher;
@end
- (void)viewDidLoad {
    [super viewDidLoad];
    self.teacher = [[Teacher alloc]init];
    // 初始化Student
    self.teacher.student = [[Student alloc]init];
    // KVC赋值
    // Teacher的公有属性
    [self.teacher setValue:@"jack" forKey:@"name"];
    // Teacher的私有属性也可以修改
    [self.teacher setValue:@"18岁" forKey:@"age"];
    [self.teacher.student setValue:@"30Kg" forKey:@"weight"];
    //(对于height,KVC先从内存中寻找对应名为height的属性,如果找不到就会自动寻找_height,然后进行相应的修改)
    [self.teacher setValue:@"183cm" forKeyPath:@"_height"];
        [self.teacher setValue:@"193cm" forKeyPath:@"height"];

    // 3.forKeyPath
    // forKeyPath包含了forKey的功能,以后使用forKeyPath就可以了。
    // forKeyPath可以利用‘ . ’运算符一层一层往下查找对象的属性
    [self.teacher setValue:@"20" forKeyPath:@"age"];
    [self.teacher setValue:@"30Kg" forKeyPath:@"student.weight"];

   // KVC取值
    NSLog(@"老师的身高:%@",[self.teacher valueForKeyPath:@"height"]);
    NSLog(@"学生的体重:%@",[self.teacher valueForKeyPath:@"student.weight"]);
    // NSLog(@"学生的体重:%@",[self.teacher.student valueForKey:@"weight"]);

    // KVO 监测student的weight变化
    // 注册观察者
    // 1.observer: 观察者 (观察self.view对象的属性的变化)
    // 2.KeyPath:  被观察属性的名称
    // 3.options:  新值,旧值
    // 4.context:  上下文 可以为kvo的回调方法传值
    [self.teacher addObserver:self forKeyPath:@"student.weight" options:(NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld) context:nil];
}
#pragma mark - KVO的回调方法(系统提供的回调方法)
/**
 * KVO的回调方法

 @param keyPath 属性名称
 @param object 被观察的对象
 @param change 变化前后的值都存储在change字典中
 @param context 注册观察者的时候,context传递过来的值
 */
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
{
    id oldW = [change objectForKey:NSKeyValueChangeOldKey];
    NSLog(@"old--%@",oldW);
    id newW = [change objectForKey:NSKeyValueChangeNewKey];
    NSLog(@"new--%@",newW);
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    [self.teacher setValue:@"75Kg" forKeyPath:@"student.weight"];
}
- (void)dealloc {
    [self.teacher removeObserver:self forKeyPath:@"student.weight"];
    self.teacher = nil;
}

从上面可以看到KVC赋值取值都有两种方式:

1、key的值必须存在且正确,如果拼写错误,会出现异常;
2、setValue: forKey:\ forKeyPath: 是根据key的值来写入对象的属性;valueForKey\ valueForKeyPath 方法根据key的值读取出对象的属性;
3、可以看出使用valueForKeyPath \ setValue:forKeyPth好一点,通过点的方式找属性符合开发习惯的。
4、在xib/Storyboard中,也可以使用KVC,下面是在xib中使用KVC把图片边框设置成圆角等:

这里写图片描述

关于系统中KVC应用例如:

// 1.最常见的修改textField里placehold的字体颜色和大小
[textField setValue:[UIColor redColor] forKeyPath:@"_placeholderLabel.textColor"];
[textField setValue:[UIFont boldSystemFontOfSize:16] forKeyPath:@"_placeholderLabel.font"];

// 2.通过KVC设置UIPageControl自定义图片修改
UIPageControl *pageControl = [[UIPageControl alloc] init]; 
 [pageControl setValue:[UIImage imageNamed:@"xx1 "] forKeyPath:@"_pageImage"];
 [pageControl setValue:[UIImage imageNamed:@"xx2"] forKeyPath:@"_currentPageImage"];
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值