demo地址:https://github.com/hanhuitao/KVO.git
概念
KVO,即:Key-Value Observing,它提供一种机制,当指定的对象的属性被修改后,则对象就会接受到通知。简单的说就是每次指定的被观察的对象的属性被修改后,KVO就会自动通知相应的观察者了。
使用场景
很多情况下,我们需要根据对象属性的变化而做出相应的事情,这就需要监听该属性的变化,比如avPlayer播放器里面,status有三种状态:
AVPlayerStatusUnknown,
AVPlayerStatusReadyToPlay,
AVPlayerStatusFailed
当status等于AVPlayerStatusReadyToPlay时代表视频已经可以播放了,我们就可以调用play方法播放了。
loadedTimeRange属性代表已经缓冲的进度,监听此属性可以在UI中更新缓冲进度,也是很有用的一个属性。
具体实现代码:
[self.playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];// 监听status属性
[self.playerItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];// 监听 loadedTimeRanges属性
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
AVPlayerItem *playerItem = (AVPlayerItem *)object;
if ([keyPath isEqualToString:@"status"]) {
if ([playerItem status] == AVPlayerStatusReadyToPlay) {
NSLog(@"AVPlayerStatusReadyToPlay");
self.stateButton.enabled = YES;
CMTime duration = self.playerItem.duration;// 获取视频总长度
CGFloat totalSecond = playerItem.duration.value / playerItem.duration.timescale;// 转换成秒
_totalTime = [self convertTime:totalSecond];// 转换成播放时间
[self customVideoSlider:duration];// 自定义UISlider外观
NSLog(@"movie total duration:%f",CMTimeGetSeconds(duration));
[self monitoringPlayback:self.playerItem];// 监听播放状态
} else if ([playerItem status] == AVPlayerStatusFailed) {
NSLog(@"AVPlayerStatusFailed");
}
} else if ([keyPath isEqualToString:@"loadedTimeRanges"]) {
NSTimeInterval timeInterval = [self availableDuration];// 计算缓冲进度
NSLog(@"Time Interval:%f",timeInterval);
CMTime duration = self.playerItem.duration;
CGFloat totalDuration = CMTimeGetSeconds(duration);
[self.videoProgress setProgress:timeInterval / totalDuration animated:YES];
}
}
上面是iOS KVO运用的实例,以下为大家介绍一个简单实用KVO的demo
目前很多宠物医生会根据狗狗的眼睛颜色的变化来判断狗狗是否患有某种疾病,监听狗狗颜色的属性,会相应的做出狗狗可能患有哪写疾病的提示。
.h文件
@interface Dog : NSObject
@property(nonatomic, copy)NSString*eyeColorStr;
@end
ViewController.m文件
#import "ViewController.h"
#import "Dog.h"
@interface ViewController ()
@property(nonatomic, strong)Dog * dog;
@property(nonatomic, strong) UILabel * dogEyeColorChangeLab;
@property(nonatomic, strong) UILabel * dogHealthLab;
@property(nonatomic, strong)NSMutableArray * dogEyeColorArray;
@end
@implementation ViewController
-(NSMutableArray*)dogEyeColorArray
{
if (!_dogEyeColorArray) {
_dogEyeColorArray=[NSMutableArray new];
}
return _dogEyeColorArray;
}
- (void)viewDidLoad {
[super viewDidLoad];
//黑色和深褐色正常,米黄色:肝脏有可能病变,苍白色:角膜炎或贫血,蓝灰色:肝炎
[self.dogEyeColorArray addObjectsFromArray:@[@"黑色",@"深褐色",@"米黄色",@"苍白色",@"蓝灰色"]];
Dog *dog = [[Dog alloc]init];
self.dog = dog;
dog.eyeColorStr = @"黑色";
UILabel *dogEyeColorChangeLab = [[UILabel alloc]init];
dogEyeColorChangeLab.frame = CGRectMake(100, 100, 200, 40);
dogEyeColorChangeLab.text = [NSString stringWithFormat:@"%@",dog.eyeColorStr];
dogEyeColorChangeLab.textAlignment=NSTextAlignmentCenter;
dogEyeColorChangeLab.backgroundColor = [UIColor cyanColor];
[self.view addSubview:dogEyeColorChangeLab];
self.dogEyeColorChangeLab = dogEyeColorChangeLab;
[dog addObserver:self forKeyPath:@"eyeColorStr" options:NSKeyValueObservingOptionNew context:nil];
UILabel *dogHealthLab = [[UILabel alloc]init];
dogHealthLab.frame = CGRectMake(100, 200, 200, 40);
dogHealthLab.text = @"狗狗眼睛健康";
dogHealthLab.textAlignment=NSTextAlignmentCenter;
dogHealthLab.backgroundColor = [UIColor cyanColor];
[self.view addSubview:dogHealthLab];
self.dogHealthLab = dogHealthLab;
}
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
int index = arc4random() % self.dogEyeColorArray.count;
self.dog.eyeColorStr = self.dogEyeColorArray[index];
}
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
{
NSLog(@"keyPath=%@,object=%@,change=%@,context=%@",keyPath,object,change,context);
self.dogEyeColorChangeLab.text = [change objectForKey:@"new"];
if ([[NSString stringWithFormat:@"%@",[change objectForKey:@"new"]] isEqualToString:@"黑色"]||[[NSString stringWithFormat:@"%@",[change objectForKey:@"new"]] isEqualToString:@"深褐色"]) {
self.dogHealthLab.text = @"狗狗眼睛健康";
}else if([[NSString stringWithFormat:@"%@",[change objectForKey:@"new"]] isEqualToString:@"米黄色"])
{
self.dogHealthLab.text = @"肝脏病变";
}else if([[NSString stringWithFormat:@"%@",[change objectForKey:@"new"]] isEqualToString:@"苍白色"])
{
self.dogHealthLab.text = @"角膜炎或贫血";
}else if([[NSString stringWithFormat:@"%@",[change objectForKey:@"new"]] isEqualToString:@"蓝灰色"])
{
self.dogHealthLab.text = @"肝炎";
}
}
@end
运行效果如下:
KVO实用.GIF
网友评论