KVO
-
可以重复添加同一observer,添加几次,但值改变时就会收到调用几次
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
测试代码如下:
- (void)viewDidLoad { [super viewDidLoad]; self.nameLable = [[UILabel alloc] init]; [self.nameLable addObserver:self forKeyPath:@"text" options:NSKeyValueObservingOptionNew context:nil]; self.nameLable.text = @"name0"; [self.nameLable addObserver:self forKeyPath:@"text" options:NSKeyValueObservingOptionNew context:nil]; self.nameLable.text = @"name1"; [self.nameLable removeObserver:self forKeyPath:@"text"]; self.nameLable.text = @"name 2"; [self.nameLable removeObserver:self forKeyPath:@"text"]; self.nameLable.text = @"name 3"; } - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context { NSLog(@"%@",change); }
输出结果
2017-05-08 17:33:45.947 Test[56608:512908] { kind = 1; new = name0; } 2017-05-08 17:33:45.948 Test[56608:512908] { kind = 1; new = name1; } 2017-05-08 17:33:45.948 Test[56608:512908] { kind = 1; new = name1; } 2017-05-08 17:33:45.948 Test[56608:512908] { kind = 1; new = "name 2"; }
-
如果对象已经被释放了,但是observer还没有被移除,会导致crash。
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'An instance 0x7fbda040c020 of class UILabel was deallocated while key value observers were still registered with it. Current observation info: <NSKeyValueObservationInfo 0x60000022aa40> (<NSKeyValueObservance 0x600000051640: Observer: 0x7fbda0406ca0, Key path: text, Options: <New: YES, Old: NO, Prior: NO> Context: 0x0, Property: 0x600000051670>
如果没有添加但是直接移除,也会crash。
Terminating app due to uncaught exception 'NSRangeException', reason: 'Cannot remove an observer <ViewController 0x7feb6160a8d0> for the key path "text" from <UILabel 0x7feb615054d0> because it is not registered as an observer.'
虽然可以在移除的时候加入try catch来防止crash,但是异常还是会被第三方crash收集统计工具上报,真是头疼的事情。
保持屏幕常亮
加入以下代码可以在用户没有任何操作的情况下屏幕一直亮着,
[[UIApplication sharedApplication] setIdleTimerDisabled:YES];
但是这个值会被系统可能被系统修改
@property(nonatomic,getter=isIdleTimerDisabled) BOOL idleTimerDisabled; // default is NO
一个重现的例子是
将idleTimerDisabled设置成yes后,调用系统的拍照,然后取消拍照,这个时候idleTimerDisabled会被设置成NO.
因为我们的应用需要保持屏幕常亮,因此需要在合适的地方加入kvo来监听这个值,如果被设置成NO,那就给它改成yes。
使用ijkplayer播放器,在播放的时候,ijkplayer会隔一段时间,大概15秒左右调用一下下面的语句来保持屏幕常亮
[[UIApplication sharedApplication] setIdleTimerDisabled:NO];
[[UIApplication sharedApplication] setIdleTimerDisabled:YES];
使用KVO以后,暂时没有发现屏幕在不应该变黑的时候黑掉。