FBKVOController 使用

- 使用way1 【正常用法】
#import "NSObject+FBKVOController.h"

    [self.KVOController observe:self.label keyPath:@"text" options:NSKeyValueObservingOptionNew block:^(id  _Nullable observer, id  _Nonnull object, NSDictionary * _Nonnull change) {
        //weakSelf
        weakSelf.count ++;
        if (weakSelf.count == 1) {
            NSLog(@"weakSelf:%@",weakSelf);
            NSLog(@"label:%@",weakSelf.label);
        }
    }];

FBKVOController 方便之处在于,不需要在dealloc里调用
-(void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath

- 使用way2【当self observe self时】
    [self.KVOControllerNonRetaining observe:self keyPath:@"numStr" options:NSKeyValueObservingOptionNew block:^(id  _Nullable observer, id  _Nonnull object, NSDictionary * _Nonnull change) {
        //weakSelf
        NSLog(@"%@",weakSelf.numStr);
    }];

  1. 这时,需要使用KVOControllerNonRetaining,否则出现retainCycle
  2. 这时,还需要手动调用removeObserver:... or self.KVOControllerNonRetaining unobserve:...
    具体原因可以看源码~
/**
 @abstract Lazy-loaded FBKVOController for use with any object
 @return FBKVOController associated with this object, creating one if necessary
 @discussion This makes it convenient to simply create and forget a FBKVOController.
 Use this version when a strong reference between controller and observed object would create a retain cycle.
 When not retaining observed objects, special care must be taken to remove observation info prior to deallocation of the observed object.
 */
@property (nonatomic, strong) FBKVOController *KVOControllerNonRetaining;

另外,这种self observe self实在没有必要用kvo,直接在setter方法中处理即可嘛。

举例

在cell中使用时, 若直接在dealloc中移除kvo

- (void)dealloc
{
    [self.KVOControllerNonRetaining unobserve:self];
}

发现友盟上 部分系统和机型会崩溃


image.png

崩溃日志

An instance 0x155536e00 of class ***Cell was deallocated while key value observers were still registered with it. Current observation info:  (  Context: 0x15685bff0, Property: 0x1568b3720>

原因: 使用KVOControllerNonRetaining注意

special care must be taken to remove observation info prior to deallocation of the observed object

   要在dealloc方法走之前 remove observationdidMoveToSuperview方法正好合适

解决方式:

- (void)didMoveToSuperview
{
    [super didMoveToSuperview];
    if (self.superview) {
        [self.KVOControllerNonRetaining observe:self keyPath: ...]
    }else {
        [self.KVOControllerNonRetaining unobserve:self];
    }
}

手绘引用图(恐怕只有自己才能看懂)


image.png

你可能感兴趣的:(FBKVOController 使用)