NSObject+BBAKVO.h 4.69 KB
//
//  NSObject+BBAKVO.h
//  BBAPods
//
//  Created by 00 on 16/5/18.
//  Copyright © 2016年 Baidu. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "BDPFoundationDefines.h"

#pragma mark - KVO添加(使用如下方式添加的KVO,会在 观察者 或者 被观察者 释放时,自动移除KVO)
/// 给当前对象(即观察者)添加KVO;该宏需结合 bdp_kvoChanged: 方法一起使用
/// 例如:若需要监听一个view对象的背景色的变动情况,则可以按如下方式使用:
/// [BBAObserve(view, backgroundColor) bdp_kvoChanged:^(id changedValue) {
///    // 处理当背景色变化时所需干的事情 ......
/// }];
#define BBAObserve(TARGET, KEYPATH) \
[self bdp_observe:(id)(TARGET) forKeyPath:@keypath(TARGET, KEYPATH)]

/// 给指定观察者添加KVO;该宏需结合 bdp_kvoChanged: 方法一起使用
#define BBAObserveOO(ObservingObj, TARGET, KEYPATH) \
[ObservingObj bdp_observe:(id)(TARGET) forKeyPath:@keypath(TARGET, KEYPATH)]


#pragma mark - KVO清除
/// 清除被观察者在当前对象(即观察者)上所监听的KVO
#define BBAObserveClean(TARGET) \
[self bdp_removeObserve:(id)(TARGET) forKeyPath:nil];

/// 清除被观察者所在指定的观察者上所监听的KVO
#define BBAObserveCleanOO(ObservingObj, TARGET) \
[ObservingObj bdp_removeObserve:(id)(TARGET) forKeyPath:nil];


#pragma mark - KVO移除
/// 移除被观察者(即TARGET对象)在当前对象(即观察者)上所监听的指定KEYPATH的KVO
#define BBAObserveRemove(TARGET, KEYPATH) \
[self bdp_removeObserve:TARGET forKeyPath:@keypath(TARGET, KEYPATH)];

/// 移除被观察者(即TARGET对象)在指定的观察者上所监听的指定KEYPATH的KVO
#define BBAObserveRemoveOO(ObservingObj, TARGET, KEYPATH) \
[ObservingObj bdp_removeObserve:(id)(TARGET) forKeyPath:@keypath(TARGET, KEYPATH)];


#pragma mark - KVO 类别
typedef void(^BBAKVOChanedBlock)(id changedValue);
typedef void(^BBAKVOChanedWithInfoBlock)(NSDictionary *change);



/// KVO便捷类,具体KVO方法,如add、remove、clean等操作,使用上述定义的对应宏定义
@interface NSObject (BBAKVO)

/// 移除 KVO 监听 (!!!推荐使用 BBAObserveRemove 相关的宏 !!!)
/// @param observedObject 被观察者
/// @param keyPath 被观察者的属性 (当keyPath为nil时,将移除observedObject上的所有属性监听)
- (void)bdp_removeObserve:(NSObject *)observedObject forKeyPath:(NSString *)keyPath;

@end


#pragma mark - 使用方不要直接调用以下方法
@interface NSObject (BBAKVOPrivate)

/// 监听被观察者的指定属性值的变化,调用者为观察者(!!!推荐使用 BBAObserve 相关的宏 !!!)
/// @param observedObject 被观察者
/// @param keyPath 被观察者的属性
/// @return 返回的是一个内部使用的类,该对象用于调用byq_kvoChanged该方法,进行设置被观察者的属性有改变时的回调
/// 不建议直接调用该方法,该方法主要用于便捷宏的使用
- (id)bdp_observe:(NSObject *)observedObject forKeyPath:(NSString *)keyPath;

/// 为 bdp_observe: forKeyPath: 方法所放回的对象提供KVO监听组装方法,使得被观察者的属性发生改变时触发回调
/// @param changed 被观察者的属性有改变时的回调
/// @note  !!!不要直接调用该方法,需结合 bdp_observe: forKeyPath: 方法使用 !!!
- (void)bdp_kvoChanged:(BBAKVOChanedBlock)changed;

/// 为 bdp_observe: forKeyPath: 方法所放回的对象提供KVO监听组装方法,使得被观察者的属性发生改变时触发回调
/// @param changedInfo 被观察者的属性有改变时的回调,会回调kvo change的相关信息 包括new 和 old值 @see NSKeyValueChangeNewKey @see NSKeyValueChangeOldKey
/// @note  !!!不要直接调用该方法,需结合 bdp_observe: forKeyPath: 方法使用 !!!
- (void)bdp_kvoChangedWithInfo:(BBAKVOChanedWithInfoBlock)changedInfo;

@end


#pragma mark - 以下方法已废弃,不要再使用
@interface NSObject (BBAKVODEPRECATED)

- (void)bba_observe:(NSObject *)observedObject forKeyPath:(NSString *)keyPath changed:(BBAKVOChanedBlock)chaned BDP_FOUNDATION_DEPRECATED("please use bdp_observe:forKeyPath:changed:");
- (void)bba_removeObserve:(NSObject *)observedObject forKeyPath:(NSString *)keyPath BDP_FOUNDATION_DEPRECATED("please use bdp_removeObserve:forKeyPath:");
- (id)bba_observe:(NSObject *)observedObject forKeyPath:(NSString *)keyPath BDP_FOUNDATION_DEPRECATED("please use bdp_observe:forKeyPath:");
- (void)bba_kvoChanged:(BBAKVOChanedBlock)changed BDP_FOUNDATION_DEPRECATED("please use bdp_kvoChanged:");
- (void)bba_kvoChangedWithInfo:(BBAKVOChanedWithInfoBlock)changedInfo BDP_FOUNDATION_DEPRECATED("please use bdp_kvoChangedWithInfo:");

@end