FBKVOController 使用

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

    [self.KVOController observe:self.label keyPath:@"text" options:NSKeyValueObservingOptionNew block:^(id  _Nullable observer, id  _Nonnull object, NSDictionary<NSKeyValueChangeKey,id> * _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<NSKeyValueChangeKey,id> * _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: <NSKeyValueObservationInfo 0x15689dbc0> ( <NSKeyValueObservance 0x15689db90: Observer: 0x15615b8c0, Key path: isdownloading, Options: <New: YES, Old: YES, Prior: NO> 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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • KVO 作为 iOS 中一种强大并且有效的机制,为 iOS 开发者们提供了很多的便利;我们可以使用 KVO 来检测...
    JzRo阅读 956评论 0 2
  • 转至元数据结尾创建: 董潇伟,最新修改于: 十二月 23, 2016 转至元数据起始第一章:isa和Class一....
    40c0490e5268阅读 1,767评论 0 9
  • 写在前面 程序设计语言中有各种各样的设计模式(pattern)和与此对应的反设计模式(anti-pattern),...
    Frankxp阅读 4,957评论 0 23
  • 该文章属于刘小壮原创,转载请注明:刘小壮[https://www.jianshu.com/u/2de707c93d...
    刘小壮阅读 48,622评论 35 227
  • 每天早上,伴随着清晨的第一缕阳光,踏出家门(那个十平米的出租房)。乘坐早晨第一趟地铁,带着梦想驶向远方。有时...
    迷途的惠子阅读 272评论 0 0