KeyValueObservation 1.0.7

KeyValueObservation 1.0.7

Joseph Newton维护。



  • Joe Newton

KeyValueObservation

Codacy Badge License MIT CocoaPods Compatible Carthage Compatible Platform Code Coverage

Carthage Cocoapods XCFramework Xcode Project

基于块的Objective-C中基于键值观察

安装

KeyValueObservation通过CocoaPodsCarthage提供。

要通过CocoaPods安装,只需在Podfile中添加以下行

pod 'KeyValueObservation'

通过Carthage安装,只需在Cartfile中添加以下行

github "SomeRandomiOSDev/KeyValueObservation"

使用

首先在Objective-C源文件的顶部导入KeyValueObservation

@import KeyValueObservation;

然后,添加观察者块就像这样做

NSString *keyPath = @"Some Key Path";
NSKeyValueObservingOptions options = ...

NSObject *observation = [object observeKeyPath:keyPath 
                                       options:options 
                                 changeHandler:^(id object, SRDKeyValueObservedChange *change) {
    
    NSLog(@"Old value = %@", [change.oldValue description]);
    NSLog(@"New value = %@", [change.newValue description]);
    ...
}];

只要返回的观察对象保持存活,键值观察就有效。一旦此对象被释放,观察者块就会被释放,不再响应变化。您也可以选择调用返回对象的invalidate方法,在对象被释放前停止观察变化。

与常规的Foundation KVO API一样,使用KVO直接观察的并不包括NSArray对象。然而,与Foundation提供的API一样,您可以观察数组中对象的更改。例如

NSString *keyPath = @"Some Key Path";
NSIndexSet *indexes = ...
NSKeyValueObservingOptions options = ...

NSObject *observation = [array observeKeyPath:keyPath
                          forObjectsAtIndexes:indexes
                                      options:options 
                                changeHandler:^(id object, SRDKeyValueObservedChange *change) {
 
    NSIndexSet *changedIndexes = change.indexes;

    // oldValue and newValue are arrays containing the before and after values of the
    // objects at the `changedIndexes`
    NSLog(@"Old value = %@", [change.oldValue description]);
    NSLog(@"New value = %@", [change.newValue description]);
    
    ...
}];

此库的另一个功能是能够在处理程序块的上下文中轻松忽略某些键值观察,而无需额外的开销。例如

@implementation FooBar

...

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
    if ([keyPath isEqualToString:@"foobar"] && object == self.foobarObject) {
        // Some action. Won't ever be called from the context of -[FooBar someMethod] given 
        // the use of -[NSObject performWhileIgnoringObservations:handler:]
    }
    else {
        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    }
}

...

- (void)someMethod {
    [self performWhileIgnoringObservations:@[[SRDKVOInfo infoWithObserved:self.foobarObject keyPath:@"foobar"]] handler:^{
        self.foobarObject.foobar = @"foobar";
    }];
}

@end

无需为您的对象添加标志来确定何时或何时不忽略特定的键值观察,您可以直接从处理程序块上下文中进行操作。在执行块期间,任何与传入方法的方法中 SRDKVOInfo 对象匹配的观察都会自动忽略。执行块完成后,观察将再次正常传递。

请注意,-[NSObject performWhileIgnoringObservations:handler:] 使用方法实现交换来能够忽略指定的观察,因此您非常重要,不要从处理程序块的上下文中为接收类对 -[NSObject observeValueForKeyPath:ofObject:change:context:] 方法进行交换。这样做可能会导致意外的结果。

贡献

无论您是提交功能请求、报告错误还是自己编写代码,这个库的所有贡献都受欢迎!请参阅CONTRIBUTING 以了解如何贡献更多详细信息。

作者

Joe Newton, [email protected]

许可

KeyValueObservation 在MIT许可下可用。有关更多信息,请参阅 LICENSE 文件。