KVO - NSKeyValueObserving

简述:在KVC 的基础上,对属性值的监听。注意KVC的使用。

一般类的 KVO

主要分为三个步骤

  • 1 注册监听:
// 使用UITextField 的 text 属性,示例。
    self.testField = [[UITextField alloc] initWithFrame:CGRectMake(0, 100, CGRectGetWidth(self.view.bounds), 40)];
    self.testField.backgroundColor = [UIColor yellowColor];
    [self.view addSubview:self.testField];
    
// 需要监听的对象 add 观察者 forkey 观察属性 描述内容
    [self.testField addObserver:self forKeyPath:@"text" options:(NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew) context:@"输入框的 输入控制"];

  • 此处的options 有4种选择
    NSKeyValueObservingOptionNew = 0x01,  新值
    NSKeyValueObservingOptionOld = 0x02,    旧值
    NSKeyValueObservingOptionInitial = 0x04,  初始化的值? 还请指导。谢谢。
    NSKeyValueObservingOptionPrior = 0x08    2次回调,变化前后。
  • 2 使用回调,对监听对象处理
// 当监听对象key 的属性值,变化时,就会有这个回调。
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
    
    if ([keyPath isEqualToString:@"text"]) {
        NSString *oldStr = change[NSKeyValueChangeOldKey];
        NSString *newStr = change[NSKeyValueChangeNewKey];
        
        if (newStr.length == 0) {
            NSLog(@"输入长度不能为0");
        } else if (newStr.length > 8) {
            NSLog(@"输入长度不能大于8");
        } else {
            NSLog(@"cool : %@ 变为 %@",oldStr,newStr);
        }
    }
}
  • 此处获取变化值时,使用的是对于的 key
FOUNDATION_EXPORT NSString *const NSKeyValueChangeNewKey;
FOUNDATION_EXPORT NSString *const NSKeyValueChangeOldKey;
FOUNDATION_EXPORT NSString *const NSKeyValueChangeNotificationIsPriorKey; 是否优先回调key。使用 NSKeyValueObservingOptionPrior 时 ,2次回调,第一次返回值1.

FOUNDATION_EXPORT NSString *const NSKeyValueChangeKindKey;
FOUNDATION_EXPORT NSString *const NSKeyValueChangeIndexesKey;
  • 3 移除监听
// 注意不要重复移除。注册-移除 一对一。
    [self.testField removeObserver:self forKeyPath:@"text"];

集合类的 KVO

其他

typedef NS_ENUM(NSUInteger, NSKeyValueChange) {
    NSKeyValueChangeSetting = 1,
    NSKeyValueChangeInsertion = 2,
    NSKeyValueChangeRemoval = 3,
    NSKeyValueChangeReplacement = 4,
};
 
typedef NS_ENUM(NSUInteger, NSKeyValueSetMutationKind) {
    NSKeyValueUnionSetMutation = 1,
    NSKeyValueMinusSetMutation = 2,
    NSKeyValueIntersectSetMutation = 3,
    NSKeyValueSetSetMutation = 4
};

@interface NSObject(NSKeyValueObserving)
 
- (void)observeValueForKeyPath:(nullable NSString *)keyPath ofObject:(nullable id)object change:(nullable NSDictionary *)change context:(nullable void *)context;

@end

@interface NSArray(NSKeyValueObserverRegistration)

- (void)addObserver:(NSObject *)observer toObjectsAtIndexes:(NSIndexSet *)indexes forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(nullable void *)context;
- (void)removeObserver:(NSObject *)observer fromObjectsAtIndexes:(NSIndexSet *)indexes forKeyPath:(NSString *)keyPath context:(nullable void *)context NS_AVAILABLE(10_7, 5_0);
- (void)removeObserver:(NSObject *)observer fromObjectsAtIndexes:(NSIndexSet *)indexes forKeyPath:(NSString *)keyPath;

- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(nullable void *)context;
- (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath context:(nullable void *)context NS_AVAILABLE(10_7, 5_0);
- (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath;

@end

@interface NSOrderedSet(NSKeyValueObserverRegistration)

- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(nullable void *)context;
- (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath context:(nullable void *)context NS_AVAILABLE(10_7, 5_0);
- (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath;

@end

@interface NSSet(NSKeyValueObserverRegistration)

- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(nullable void *)context;
- (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath context:(nullable void *)context NS_AVAILABLE(10_7, 5_0);
- (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath;

@end

@interface NSObject(NSKeyValueObserverNotification)

- (void)willChangeValueForKey:(NSString *)key;
- (void)didChangeValueForKey:(NSString *)key;
- (void)willChange:(NSKeyValueChange)changeKind valuesAtIndexes:(NSIndexSet *)indexes forKey:(NSString *)key;
- (void)didChange:(NSKeyValueChange)changeKind valuesAtIndexes:(NSIndexSet *)indexes forKey:(NSString *)key;
- (void)willChangeValueForKey:(NSString *)key withSetMutation:(NSKeyValueSetMutationKind)mutationKind usingObjects:(NSSet *)objects;
- (void)didChangeValueForKey:(NSString *)key withSetMutation:(NSKeyValueSetMutationKind)mutationKind usingObjects:(NSSet *)objects;

@end

@interface NSObject(NSKeyValueObservingCustomization)
+ (NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key NS_AVAILABLE(10_5, 2_0);
+ (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key;
@property (nullable) void *observationInfo NS_RETURNS_INNER_POINTER;

@end

你可能感兴趣的:(KVO - NSKeyValueObserving)