KVO监听

Main.m

#import "Children.h"
#import "Nurse.h"

int main(int argc, const char * argv[])
{

    Children *children = [[Children alloc] init];

    Nurse *nurse = [[Nurse alloc] initWithChildren:children];

    [[NSRunLoop currentRunLoop] run];

    [children release];
    [nurse release];

    return 0;
}

Children.h

@interface Children : NSObject {

    NSInteger _happyValue;

}

@property (nonatomic, assign) NSInteger happyValue; //欢乐值
@property (nonatomic, assign) NSInteger hungryValue;    //饥饿值

Children.m

@implementation Children

- (id)init {

    self = [super init];

    if (self) {
        //开启定时器
        [NSTimer scheduledTimerWithTimeInterval:1
                                         target:self
                                       selector:@selector(timeAction:)
                                       userInfo:nil
                                        repeats:YES];
        _happyValue = 100;
        _hungryValue = 100;
    }

    return self;
}

- (void)timeAction:(NSTimer *)time {

    NSInteger value1 = _happyValue;
    NSInteger value2 = _hungryValue;

    NSLog(@"happlValue:%ld",_happyValue);
    NSLog(@"_hungryValue:%ld",_hungryValue);

    //方式一:这样不能触发KVO,只有通过setter方法才能触发
//    _happyValue --;

    //new和old的界线是:调用setter方法

    //方式二:100 99  setter 99:错误,新旧值一样
//    [self setHappyValue:--_happyValue];

    //方式三:100 100  setter 99
    [self setHappyValue:--value1];
    [self setHungryValue:--value2];

    //KVC:也可以触发
//    [self setValue:[NSNumber numberWithInteger:--value] forKey:@"happyValue"];

}

Nurse.h

@class Children;

@interface Nurse : NSObject {

    Children *_chiledren;

}

- (id)initWithChildren:(Children *)children;

Nurse.m

#import "Children.h"

@implementation Nurse

- (id)initWithChildren:(Children *)children {

    self = [super init];

    if (self) {
        _chiledren = [children retain];

        //使用KVO监听小孩的属性happyValue变化
        [_chiledren addObserver:self
                     forKeyPath:@"happyValue"
                        options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
                        context:NULL];

        //使用KVO监听小孩的属性hungryValue变化
        [_chiledren addObserver:self
                     forKeyPath:@"hungryValue"
                        options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
                        context:NULL];
    }

    return self;
}

//小孩属性变化的时候,接收事件的方法
- (void)observeValueForKeyPath:(NSString *)keyPath  //观察的对象的属性名
                      ofObject:(id)object   //观察的对象
                        change:(NSDictionary *)change
                       context:(void *)context {

//    NSLog(@"change:%@",change);

    NSNumber *newNum = [change objectForKey:@"new"];
    int value = [newNum intValue];

    if ([keyPath isEqualToString:@"happyValue"]) {

        if (value < 90) {
            [self play];
        }
    }

    if ([keyPath isEqualToString:@"hungryValue"]) {

        if (value < 85) {
            NSLog(@"保姆给小孩喂饭");
            _chiledren.hungryValue = 100;
        }
    }

}

//陪小孩玩
- (void)play {

    NSLog(@"保姆和小孩玩");

    _chiledren.happyValue = 100;

}

- (void)dealloc {

    //移除观察者
    [_chiledren removeObserver:self forKeyPath:@"happyValue"];
    [_chiledren removeObserver:self forKeyPath:@"hungryValue"];

    [_chiledren release];

    [super dealloc];

}
时间: 2024-07-30 10:13:56

KVO监听的相关文章

iOS: 使用KVO监听控制器中数组的变化

一.介绍: KVO是一种能动态监听到属性值的改变的方式,使用场景非常广泛,这里我只讲如何监听控制器ViewController中数组的变化. 二.了解: 首先我们应该知道KVO是不能直接监听控制器ViewController数组的变化的,需要将数组定义在模型中,然后控制器ViewController持有模型对象,通过该对象才能监听. 三.步骤: <1>在控制器ViewController类中定义一个模型类Model,并在该类中声明一个可变的数组属性modelArray并进行懒加载,其实它最终就

用KVO监听控件属性的改变(observeValueForKeyPath)

创建一个测试的UIButton #import "ViewController.h" @interface ViewController () @property(nonatomic, strong)UIButton *button; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; self.button = [[UIButton alloc] initWithFrame:CG

UIAlertController 自定义输入框及KVO监听

UIAlertController极大的灵活性意味着您不必拘泥于内置样式.以前我们只能在默认视图.文本框视图.密码框视图.登录和密码输入框视图中选择,现在我们可以向对话框中添加任意数目的UITextField对象,并且可以使用所有的UITextField特性.当向对话框控制器中添加文本框时,需要指定一个用来配置文本框的代码块. UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"文本

ios监听

1.ios中用来监听的方法 代理/通知/block/KVO(监听对象属性变化) 代理:一对一关系,不能用在单例模式?但是为什么不能用在单例模式呢?求解 通知:一对多,发生事件的时候发送通知 KVO:用来监听对象属性的变化(在监听frame时可能会出现问题,具体遇到问题后期我会上代码展示) 2.切记!!通知:发送通知的代码所在的线程,就是通知方法执行的线程!!! 使用的时候需要注意当我们发送了一个通知,想让监听这个通知的对象刷新UI界面,如果该通知不是在 [NSOperationQueue mai

KVO-对象属性值改变监听

key value observer 键值观察 一.使用方法: 以person对象为例,person中的属性name,监听name值改变的方法 //添加监听的属性keyPath  options:要监听的是新值还是旧值 [self.person addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil]; //监听

iOS开发之--为UITextField监听数值变化的三种方法

项目中有个验证码输入直接验证跳转页面,用的RAC来监听textfield的输入值,如下: @weakify(self); [self.codeView.textField.rac_textSignal subscribeNext:^(NSString *value) { @strongify(self); self.value = value; //也可以直接在这里写想要执行的操作 }]; //当self.value的值变化时调用Block,这是用KVO的机制,RAC封装了KVO [RACObs

Swift中KVO(监听)的使用方法及注意事项

---恢复内容开始--- 相信研究swift语言的开发者都多多少少了解或者精通Objective—C语言,熟练掌握Objective—C语言的开发者,在学习swift语言的过程中,是比较快速,而又轻松的.本人就是一位熟练掌握OC语言,后开始研究的swift.在学习swift语言的过程中,笔者建议有OC基础的开发者,在写swift的代码过程中,再写一下OC中的代码,二者相互比较,相信你能找到快速学会swift语言的方法.资深,有耐心和有天赋的开发者,相信能在一周左右,能够运用swift开发项目.其

KVO键值监听

KVO 键值监听:当我想知道一个对象的属性是否发生改变的时候 做出响应,就需要添加监听keypath 和 key的区别keypath会自动寻找子类的属性key只会寻找当前类的属性添加键值监听[person addObserver:self forKeyPath:@“属性” options:.....] 当键值发生改变的时候调用-(void)obserValueForKeyPath:(NSString ) 底层实现:运行的时候 创建一个当前类的子类,重写子类的set方法 系统 建立了一个子类,然后

手动设定实例变量的KVO实现监听

如果将一个对象设定成属性,这个属性是自动支持KVO的,如果这个对象是一个实例变量,那么,这个KVO是需要我们自己来实现的. 以下给出源码供君测试: Student.h 与 Student.m // // Student.h // SuperNotification // // Copyright (c) 2014年 Y.X. All rights reserved. // #import <Foundation/Foundation.h> @interface Student : NSObje