KVO Block: Block-KVO vs THObserversAndBinders vs KVOController

Block-KVO vs THObserversAndBinders vs KVOController .

What are the pros and cons of each? Which one is better and why?

UPDATE: In the end, I tend to use Objective-Chain to handle KVO. ReactiveCocoa is also an option, but perhaps too overboard for this.

+6
source share
2 answers

First of all, let me say that this is a vivid example of a subjective question, which probably should not be asked here - you are certainly a well-established member here, and I am sure that you already knew this.

But since you asked, I will try to answer your subjective question as unpredictably as possible - although this is not the best question for Stack Overflow, this is a good question in general, and I'm sure several Googlers will be here looking for an answer, subjective or not!


First of all, if your only / main complaint about KVO is the syntax (as you mentioned in the comments on your question), do not go after the Objective-Chain or its inspiration, ReactiveCocoa . While they have an incredible amount of utility , none of them are worth their weight or complexity just for the more accessible KVO syntax.

Of the three libraries that you mentioned, KVOController is most often used โ€” between simple syntax and to be sure of thread safety, you can let a large number of GitHub stars speak for themselves. This is my recommendation of the three originally published options.

Other options, which also seem easy and great syntaxes, also have their advantages - Block-KVO is the only option for three sports for the MIT license instead of BSD, so if this is the preference of the need for your project, keep this in mind and THObserversAndBinders , despite something that has not been updated since the end of 2013, excellent documentation and the lack of ownership of Facebook, if this is also your thing.


Hopefully this will give you an objective list that will help you choose the best option - and don't forget to leave it less open the next time :)

+12
source

Here's a minimal working idea (the KVO style puts me off too). The idea is to transfer a block in the context of KVO, and then call it when an observation fires.

 // NSObject+KVOBlock.h #import <Foundation/Foundation.h> @interface NSObject (KVOBlock) // invoke the block when the receiver value at keyPath changes // block params are the receiver, the keyPath and the old value - (void)observeKeyPath:(NSString *)keyPath withBlock:(void (^)(id, NSString *, id))block; - (void)unobserveKeyPath:(NSString *)keyPath; @end // NSObject+KVOBlock.m #import "NSObject+KVOBlock.h" @implementation NSObject (KVOBlock) - (void)observeKeyPath:(NSString *)keyPath withBlock:(void (^)(id, NSString *, id))block { [self addObserver:self forKeyPath:keyPath options:NSKeyValueObservingOptionOld context:(__bridge void *)(block)]; } - (void)unobserveKeyPath:(NSString *)keyPath { [self removeObserver:self forKeyPath:keyPath]; } - (void) observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(NSDictionary*)change context:(void*)context { void (^block)(id, NSString *, id) = (__bridge void (^)(id, NSString *, id))context; block(self, keyPath, [change objectForKey:NSKeyValueChangeOldKey]); } @end 

Call it like this:

 // assume a class called SomeObject with an instance called someObject someObject.someProperty = @"Bar"; [someObject observeKeyPath:@"someProperty" withBlock:^(SomeObject *object, NSString *keyPath, NSString *oldValue) { // avoid referring directly to 'someObject' in this block, since it retains // the block via the kvo context, thereby causing a retain cycle. The first // param ('object') is exactly equal to someObject. So use that instead. NSLog(@"object=%@, keyPath=%@, oldValue=%@, newValue=%@", object, keyPath, oldValue, object.someProperty); }]; // at any point after this, when you change someProperty, the block will be invoked self.object.someProperty = @"Foo"; 

I did a mini test with the code above and confirmed that it worked, at least in the case shown here. The console output looked like this:

 <SomeObject :0xblahblah>, keyPath=someProperty, oldValue=Bar, newValue=Foo 
+4
source

Source: https://habr.com/ru/post/972035/


All Articles