demo地址:https://github.com/hanhuitao/KVO.git
概念
KVO,即:Key-Value Observing樟蠕,它提供一種機(jī)制使碾,當(dāng)指定的對(duì)象的屬性被修改后悔据,則對(duì)象就會(huì)接受到通知巷疼。簡(jiǎn)單的說(shuō)就是每次指定的被觀察的對(duì)象的屬性被修改后宇整,KVO就會(huì)自動(dòng)通知相應(yīng)的觀察者了晌坤。
使用場(chǎng)景
很多情況下程奠,我們需要根據(jù)對(duì)象屬性的變化而做出相應(yīng)的事情丈牢,這就需要監(jiān)聽該屬性的變化,比如avPlayer播放器里面瞄沙,status有三種狀態(tài):
AVPlayerStatusUnknown,
AVPlayerStatusReadyToPlay,
AVPlayerStatusFailed
當(dāng)status等于AVPlayerStatusReadyToPlay時(shí)代表視頻已經(jīng)可以播放了己沛,我們就可以調(diào)用play方法播放了。
loadedTimeRange屬性代表已經(jīng)緩沖的進(jìn)度距境,監(jiān)聽此屬性可以在UI中更新緩沖進(jìn)度申尼,也是很有用的一個(gè)屬性。
具體實(shí)現(xiàn)代碼:
[self.playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];// 監(jiān)聽status屬性
[self.playerItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];// 監(jiān)聽 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;// 獲取視頻總長(zhǎng)度
CGFloat totalSecond = playerItem.duration.value / playerItem.duration.timescale;// 轉(zhuǎn)換成秒
_totalTime = [self convertTime:totalSecond];// 轉(zhuǎn)換成播放時(shí)間
[self customVideoSlider:duration];// 自定義UISlider外觀
NSLog(@"movie total duration:%f",CMTimeGetSeconds(duration));
[self monitoringPlayback:self.playerItem];// 監(jiān)聽播放狀態(tài)
} else if ([playerItem status] == AVPlayerStatusFailed) {
NSLog(@"AVPlayerStatusFailed");
}
} else if ([keyPath isEqualToString:@"loadedTimeRanges"]) {
NSTimeInterval timeInterval = [self availableDuration];// 計(jì)算緩沖進(jìn)度
NSLog(@"Time Interval:%f",timeInterval);
CMTime duration = self.playerItem.duration;
CGFloat totalDuration = CMTimeGetSeconds(duration);
[self.videoProgress setProgress:timeInterval / totalDuration animated:YES];
}
}
上面是iOS KVO運(yùn)用的實(shí)例垫桂,以下為大家介紹一個(gè)簡(jiǎn)單實(shí)用KVO的demo
目前很多寵物醫(yī)生會(huì)根據(jù)狗狗的眼睛顏色的變化來(lái)判斷狗狗是否患有某種疾病师幕,監(jiān)聽狗狗顏色的屬性,會(huì)相應(yīng)的做出狗狗可能患有哪寫疾病的提示诬滩。
.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];
//黑色和深褐色正常霹粥,米黃色:肝臟有可能病變灭将,蒼白色:角膜炎或貧血,藍(lán)灰色:肝炎
[self.dogEyeColorArray addObjectsFromArray:@[@"黑色",@"深褐色",@"米黃色",@"蒼白色",@"藍(lán)灰色"]];
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:@"藍(lán)灰色"])
{
self.dogHealthLab.text = @"肝炎";
}
}
@end
運(yùn)行效果如下: