OC学习日记11-KVC和KVO

KVC和KVO

这里写图片描述

前言

相信在OC里面自学最有难度就是这个KVC和KVO了,很多人都不明白这个东西是什么,经过老师的讲解和我自己的理解,我是这样看的:KVC是在原来OC旧版本里面还没有设置器跟访问器的时候,用于对受保护的成员变量进行设置和访问的,所以我们要用KVC进行读写,在现在,KVC最大的作用就是动态访问某些变量的时候,缩减代码量,提高我们程序的可扩展性。

KVC

设计模式 -观察者模式

   设计模式是用来解决某一特定问题

观察者模式

什么是观察者模式?
 在工程中,一些类去观察‘A’类,当‘A’类发生变化时,这些类就会收到消息,做出相应反应。
什么时候使用观察者模式?
 当一个类需要发送消息给多个类的时候,就用观察者模式。
观察者模式的作用?
 一对多的消息发送
在OC中如何实现观察者模式?
 OC中,观察者模式的设计基础,KVC/KVO
 KVC(键值编码 Key-Value Coding)
 KVC提供了一种在运行时而非编译时动态访问对象属性与实例变量的方式。

创建一个学生Student的类

@interface Student : NSObject
{
    NSString *_name;
    NSInteger _age;
}
@property (nonatomic,strong)NSString *address;

重写description方法

@implementation Student
-(NSString *)description{
    return [NSString stringWithFormat:@"My name is %@,%lu years old,living in %@",_name,_age,_address];
}

setValue forKey和valueForKey

设置一个学生类的对象,以及用setValue forKey的方式对它的成员变量赋值。
    Student *stu1=[Student new];
    [stu1 setValue:@"Rick" forKey:@"_name"];
    [stu1 setValue:@25 forKey:@"_age"];
    [stu1 setValue:@"GZ" forKey:@"_address"];
    NSLog(@"%@",stu1);
用valueForKey进行访问
NSString *name=[stu1 valueForKey:@"_name"];
NSNumber *age=[stu1 valueForKey:@"_age"];
NSString *address=[stu1 valueForKey:@"_address"];
NSLog(@"name = %@, age = %@,address = %@",name,age,address);

动态访问

动态访问某些属性时,使用一些可以运行时而不是编译时改变的值
student.h文件中
@property (nonatomic,assign)int p1;
@property (nonatomic,assign)int p2;
@property (nonatomic,assign)int p3;
-(int)getValuePropertyName:(NSString *)name;
-(int)getNewValuePropertyName:(NSString *)name;
我们可以通过写两个PropertyName方法去说明一下动态访问
student.m文件中
-(int)getValuePropertyName:(NSString *)name{
    NSString *stu1=@"p1";
    NSString *stu2=@"p2";
    NSString *stu3=@"p3";
    if ([stu1 isEqualToString:name ]) {
        return self.p1;
    }
    else if ([stu2 isEqualToString:name ]) {
        return self.p2;
    }
    else if ([stu3 isEqualToString:name ]) {
        return self.p3;
    }
    else
    return 0;
}
-(int)getNewValuePropertyName:(NSString *)name{
    NSNumber *number=[self valueForKey:name];
    return [number intValue];
}
主函数main.m
    stu1.p1=1;
    stu1.p2=2;
    stu1.p3=3;
    int a=[stu1 getValuePropertyName:@"p1"];
    NSLog(@"%d",a);

    int b=[stu1 getNewValuePropertyName:@"p1"];
    NSLog(@"%d",b);
    Book *book=[[Book alloc]init] ;

键路径编码

@interface Book : NSObject
{
    NSString *_bookName;
}

在student.h文件中导入Book的头文件:#import “Book.h”
在主函数main.m中

    [stu1 setValue:book forKeyPath:@"_book"];
    [stu1 setValue:@"葵花宝典,欲练神功" forKeyPath:@"_book._bookName"];
    NSString *bookName=[stu1 valueForKeyPath:@"_book._bookName"];
   NSLog(@"bookName = %@",bookName);

KVO

KVO的由来:

 在编程的过程中,我们经常需要判断目标是否发生变化,以便及时地做出对应的处理,此时苹果公司就提供了一种策略,即‘OC运行时’提供了‘KVO’技术,其中‘KVO’是基于‘KVC’实现
 KVO的实现:
 1.注册成为观察者
 2.观察者定义KVO回顾
 3.移除观察者
 */


Hero *hero=[Hero new];

[hero setValue:@100 forKey:@"_hp"];
Observer *observer = [[Observer alloc]initWithHero:hero];
[hero setValue:@300 forKey:@"_hp"];
[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(Time:) userInfo:nil repeats:YES];
_hero = hero;
_observer=observer;

}
-(void)Time:(NSTimer *)timer{
NSUInteger _cutHP=[[_hero valueForKey:@”_hp”]integerValue];

_cutHP -=50;
if (_cutHP<=0) {
    NSLog(@"英雄挂了");
    [_hero setValue:@0 forKey:@"_hp"];
    [timer invalidate];

}
else{
    [_hero setValue:@(_cutHP) forKey:@"_hp"];
}

}

#import <Foundation/Foundation.h>
#import "Hero.h"
@interface Observer : NSObject
@property (nonatomic,strong)Hero *hero;
-(id)initWithHero:(Hero *)hero;
@end
-(id)initWithHero:(Hero *)hero{
    if (self =[super init]) {

        self.hero=hero;
        //1.注册成为观察者
        /*表示接受通知的对象,即观察者,通常self
         建路径参数,要观察的键路径
         标志KVO希望变化如何传递给观察者,这些值可以使用‘|’进行多选
         上下文内存区,通常为nil
         */
        [self.hero addObserver:self forKeyPath:@"_hp" options:NSKeyValueObservingOptionNew context:nil];



    }
    return self;
}


//定义回溯
-(void)observeValueForKeyPath:(NSString *)keyPath
                     ofObject:(id)object
                       change:(NSDictionary<NSString *,id> *)change
                      context:(void *)context{
    NSLog(@"%@",[change objectForKey:NSKeyValueChangeNewKey]);
}

-(void)dealloc{
    NSLog(@"我挂了");
    /*
     移除的观察者对象
     观察的键路径
     */
    [self.hero removeObserver:self forKeyPath:@"_hp"];
}
@interface Hero : NSObject
{
    NSUInteger _hp;
}
@end
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值