在ViewController.m文件里
#import "ViewController.h"
#import "Hero.h"
#import "Obsener.h"
@interface ViewController ()
{
Hero *hero;//设置全局变量
Obsener *obsener;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//KVO
/*
KVO的由来:在编程的过程中,我们经常需要判断目标是否发生变化,以便及时的做出对应的处理.此时苹果公司就提供了一种策略,即'OC运行时'提供了'KVO'技术.其中'KVO'是基于'KVC'实现的
KVO的实现:
1.要注册成观察者
2.观察者定义KVO回调
3.移除观察者
*/
hero = [Hero new];
[hero setValue:@100 forKey:@"_HP"];//KVC方式赋值
obsener = [[Obsener alloc] initWithHero:hero];
[hero setValue:@300 forKey:@"_HP"];
[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(change:) userInfo:nil repeats:YES];
//所有如果在主线程中可以不用写NSRunLoop做运行环境的语句,但是如果在非主线程中就要将NSTimer加入到改线程的NSRunLoop中,并启动NSRunLoop才行. [[NSRunLoop currentRunLoop] run]
// NSLog(@"man RunLoop = %@",[NSRunLoop mainRunLoop]);
}
-(void)change:(NSTimer *)timer
{
NSLog(@"1111");
NSUInteger _curHP = [[hero valueForKey:@"_HP"] integerValue];
_curHP -= 50;
if (_curHP<=0)
{
[hero setValue:@0 forKey:@"_HP"];
[timer invalidate];
}
else
{
[hero setValue:[NSNumber numberWithInteger:_curHP] forKey:@"_HP"];
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
在Hero.h文件里
@interface Hero : NSObject
{
NSUInteger _HP;
}
@end
在Obsener.h文件里
#import <Foundation/Foundation.h>
#import "Hero.h"
@interface Obsener : NSObject
@property(nonatomic,retain)Hero *hero;
-(id)initWithHero:(Hero *)hero;
@end
在Obsensr.m文件里
#import "Obsener.h"
@implementation Obsener
-(id)initWithHero:(Hero *)hero
{
if (self = [super init])
{
self.hero = hero;
//注册监听者
/*
NSKeyValueObservingOptionNew 把更改之后的值提供给观察者的回调方法 p225
NSKeyValueObservingOptionOld 把更改之前的值提供给观察者的回调方法
NSKeyValueObservingOptionInitial 把初始化的值提供给观察者的回调方法,一旦注册,立马就会调用一次,通常它会带有新值,而不会带有旧值
NSKeyValueObservingOptionPrior
*/
[self.hero addObserver:self forKeyPath:@"_HP" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
}
return self;
}
//定义KVO回调
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
{
NSLog(@"change = %@",change);
/*
change是一个字典 包含的key如下 p226
NSKeyValueChangeKindKey
NSKeyValueChangeNewKey 新值
NSKeyValueChangeOldKey 旧值
NSKeyValueChangeIndexesKey
NSKeyValueChangeNotificationIsPriorKey
*/
}
//移除监听者
-(void)dealloc
{
/*
NSObject类定义了一个方法叫做dealloc,当对象没有拥有者并且内存要被回收时,系统会自动调用dealloc方法.dealloc的责任是释放对象自己的内存,释放所有它控制的资源,包括释放所有实例变量的所有权
*/
[self.hero removeObserver:self forKeyPath:@"_HP"];
NSLog(@"I am die");
}
@end