KVO 存在 key 依赖的情况
重写方法
keyPathsForValuesAffectingValueForKey
或者
keyPathsForValuesAffecting<Key>
(推荐)
上面两个方法可以解决 key 依赖的情况
key 依赖
类 KVO_DependentKeys 有三个属性,fullName,firstName,lastName
fullName 依赖于其他两个属性 firstName,lastName
KVO_DependentKeys.m 实现
- (NSString *)fullName {
return [NSString stringWithFormat:@"%@ %@",_firstName, _lastName];
}
// 推荐使用 keyPathsForValuesAffecting<Key> , 比下面的方法要好 keyPathsForValuesAffectingValueForKey
+ (NSSet<NSString *> *)keyPathsForValuesAffectingValueForKey:(NSString *)key{
// 必须先调用父类方法
NSSet *keyPaths = [super keyPathsForValuesAffectingValueForKey:key];
if ([key isEqualToString:@"fullName"]) {
NSArray *affectingKeys = @[@"lastName",@"firstName"];
keyPaths = [keyPaths setByAddingObjectsFromArray:affectingKeys];
}
return keyPaths;
}
//keyPathsForValuesAffecting<Key>
+ (NSSet<NSString *> *)keyPathsForValuesAffectingFullName{
return [NSSet setWithObjects:@"lastName",@"firstName", nil];
}
外部调用
KVO_DependentKeys *obj = [[KVO_DependentKeys alloc] init];
[obj addObserver:self forKeyPath:@"fullName" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];
obj.firstName = @"wang";
obj.lastName = @"bin bin";
NSLog(@"fullName = %@",obj.fullName);
[obj removeObserver:self forKeyPath:@"fullName"];
keyPath 依赖
如果 KVO_DependentKeys
的属性 information
依赖于 另外一个属性内部的属性 target.age
和 target.grade
,也可以使用上面的机制实现 kvo
KVO_target 的属性
@property (nonatomic, readwrite) int age;
@property (nonatomic, readwrite) int grade;
KVO_DependentKeys 的属性
@property (nonatomic, strong) NSString *information; /// 信息
@property (nonatomic, strong) KVO_target *target; /// keyPath 依赖
KVO_DependentKeys .m 文件
+ (NSSet<NSString *> *)keyPathsForValuesAffectingInformation{
return [NSSet setWithObjects:@"target.age",@"target.grade", nil];
}
外部调用
// keyPath 依赖
KVO_target *target;
{
target = [[KVO_target alloc] init];
target.age = 20;
target.grade = 5;
}
KVO_DependentKeys *objKeyPath = [[KVO_DependentKeys alloc] init];
{
objKeyPath.target = target;
[objKeyPath addObserver:self forKeyPath:@"information" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];
target.age = 22;
target.grade = 7;
NSLog(@"information = %@",objKeyPath.information);
[objKeyPath removeObserver:self forKeyPath:@"information" ];
}