Skip to content
A simpler key-value observing API (with blocks!)
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


Simplified key-value observing for the masses. This is a single-header-single-implementation-file library. Supports iOS 4.0 and Mac OS X 10.6 and above.


Add the TastyKVO subdirectory as a group to your project, #import "NSObject+TastyKVO.h" and start using the tasty API.


The methods provided by TastyKVO are documented in the NSObject+TastyKVO.h file. The following examples demonstrate some common use cases.

Using blocks

// MyObject.m

- (void)observeNature
    [_nature addTastyObserver:self
                    withBlock:^(MyObject *self, id target, NSDictionary *change) {
                                  // take measures

- (void)dealloc
    [_nature removeTastyObserver:self];
    [super dealloc];

Using custom selector

// MyObject.m

@implementation MyObject

- (void)aMethod

- (id)initWithTarget:(id)target
    if ((self = [super init])) {
        _target = target;
        [_target addTastyObserver:self
    return self;

- (void)dealloc
   [_target removeTastyObserver:self];
   [super dealloc];

Implicitly storing the target

You are not obliged to store the target, the library is already doing it for you. Simply use the stopObservingAllTargets method to unregister from KVO notifications.

- (id)observeExternalNature:(id)nature
    [self observeChangesIn:nature

- (void)dealloc
    [self stopObservingAllTargets];
    [super dealloc];

Observing multiple properties

The code below

TastyBlock block = ...;
[target addTastyObserver:self forKeyPath:@"property|anotherProperty" withBlock:block];

is equivalent to the following code

TastyBlock block = ...;
[target addTastyObserver:self forKeyPath:@"property" withBlock:block];
[target addTastyObserver:self forKeyPath:@"anotherProperty" withBlock:block];

Memory Management

The library has not been tested with ARC.

The library has been tested with GC somewhat, but not in production code.

It is important that you unregister an object from KVO notifications before it is deallocated. Similarly, a target must remove all of its observers prior to deallocation. Failing to do so may cause unpredictable consequences which can't even be tested reliably. Luckily, TastyKVO provides a way to enforce this policy automatically.

There are two macros that you can define in order to enable automatic observer removal.

  1. TASTYKVO_ENABLE_AUTOREMOVE. When defined, each target (the object which has at least one observer) will remove all of its observers prior to deallocation.

  2. TASTYKVO_ENABLE_AUTOUNREGISTER. When defined, each observer will stop observing all of its targets prior to deallocation.

When you define both macros, either at the top level in your project's build settings or only for the file NSObject+TastyKVO.m, you no longer need to call any of the stopObserving... or removeTastyObserver... methods.

Implementation details

Under the hood, the automatic removal and unregistration are implemented by means of swizzling the dealloc method. That is, when you register an observer via one of the addTastyObserver... or observeChangesIn... methods, the object's own implementation of dealloc is replaced with a custom one (the object being the target, the observer, or both, depending on the macros defined). This new implementation calls removeAllTastyObservers or stopObservingAllTargets first and then invokes the original dealloc method of the object.

License & Feedback

The code is in the public domain. I encourage you to get it, try it, use it, hack on it, and share your modifications with the world.

If you have found a defect, please file an issue on the project's GitHub page.

If you want your modifications to be merged with the main project fork, send me a pull request.

If you have suggestions, comments or other kinds of feedback, don't hesitate to contact me directly. My name is Alex.

Originally written by Alexei Sholik in February 2012.

Something went wrong with that request. Please try again.