iOS KVO (3)KVO键之间的依赖
2018-05-22 本文已影响8人
奔跑吧小蚂蚁
依赖,故名思义,有单项依赖,双向依赖,多项依赖。在项目开发中有的时候我们会遇到这样的问题,我们需要监控变量A的变化,而变量A的变化依赖于变量B,C的变化,变量B,C不改变,A就不会改变。变量B,C任一改变,A就会发生改变。是的我们可以同事监控变量B,C但是如果是100对象呢 需要对100个变量进行监控吗? 问题已经清晰我们直接上代码吧。
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic,copy)NSString *fullName;
@property (nonatomic,copy)NSString *firstName;
@property (nonatomic,copy)NSString *lastName;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self addObserver:self forKeyPath:@"fullName" options:NSKeyValueObservingOptionNew context:nil];
self.firstName = @"WANG";
self.lastName = @"Gang";
self.firstName = @"LI";
self.lastName = @"QIANG";
}
- (NSString *)fullName{
return [NSString stringWithFormat:@"%@ %@",self.firstName,self.lastName];
}
+ (NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key {
NSSet *keyPaths = [super keyPathsForValuesAffectingValueForKey:key];
if ([key isEqualToString:@"fullName"]) {
NSArray *affectingKeys = @[@"lastName", @"firstName"];
keyPaths = [keyPaths setByAddingObjectsFromArray:affectingKeys];
}
return keyPaths;
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
NSLog(@"%@",change);
}
- (void)dealloc{
[self removeObserver:self forKeyPath:@"fullName"];
}
打印数据
2018-05-22 16:00:42.137928+0700 KVODemo[60579:2029281] {
kind = 1;
new = "WANG (null)";
}
2018-05-22 16:00:42.138129+0700 KVODemo[60579:2029281] {
kind = 1;
new = "WANG Gang";
}
2018-05-22 16:00:42.138259+0700 KVODemo[60579:2029281] {
kind = 1;
new = "LI Gang";
}
2018-05-22 16:00:42.138383+0700 KVODemo[60579:2029281] {
kind = 1;
new = "LI QIANG";
}
总结:
1.看到这些时候我想你已经明白了 fullName的改变依赖于firstName和lastName 只有lastName和lastName改变fullName才会改变,需要注意的是,虽然KeyPath是fullName 但是你对fullName进行赋值,也不会调用监控的方法,因为已经讲监控对象指向了依赖对象。
keyPathsForValuesAffectingValueForKey添加依赖的方法,此方法同样遵循KVC的命名查找规则
你也可以通过实现 keyPathsForValuesAffecting<Key> 方法来达到前面同样的效果,这里的<Key>就是属性名,不过第一个字母要大写,用前面的例子来说就是这样:
+ (NSSet *)keyPathsForValuesAffectingFullName {
return [NSSet setWithObjects:@"lastName", @"firstName", nil];
}
未完,待续