• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Implementing a KVO/Bindings-Compliant Bridge-Pattern in Cocoa
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Implementing a KVO/Bindings-Compliant Bridge-Pattern in Cocoa


  • Subject: Re: Implementing a KVO/Bindings-Compliant Bridge-Pattern in Cocoa
  • From: Ron Lue-Sang <email@hidden>
  • Date: Fri, 17 Oct 2008 19:35:42 -0700


On Oct 15, 2008, at 2:53 AM, Sebastian Morawietz wrote:

Hi folks,

I'm trying to implement a simple object bridge in cocoa where the
bridge object acts as a kvo/bindings-compliant drop in for some
arbitrary other NSObject-instance.

Here is my problem (more details in the attached code):

A Bridge object acts as a drop in for a Person-Object, with an
NSString* property called name and an Address* property address.
Binding to the keyPath "name" or "address" of the Bridge works nicely.
Trouble starts when binding some object to the keyPath
"address.street" of the bridge and a new Address-Object is set for
Person's address property. That results in KVO-related exceptions that
look like this:

* Cannot remove an observer <NSKeyValueObservance 0x126b00> for the
key path "street"
* from <Address 0x12f1d0> because it is not registered as an observer

This happens even though the bridge notices the change in the
"address"-Property and emits a
willChangeValueForKeyPath/didChangeValueForKeyPath tuple.

The attached code produces the the problem. The file contains a
main-function can be compiled and run with

* gcc -o test BridgeDemo.m -framework AppKit -framework Foundation; ./test

If you know a solution to this problem or can offer me a better
approach solving the same problem you make me a very happy programmer.



Don't do this. You're lying by doing this. Kittens die when you do this.

- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id) object change:(NSDictionary *)change context:(void *)context
{
NSLog( @">>>> Detected Change in keyPath: %@", keyPath );
[self willChangeValueForKey:keyPath];
[self didChangeValueForKey:keyPath];
}


Alternatives include:

1) Registering for the "prior" notification by passing NSKeyValueObservingOptionPrior instead of using "new" as an option when registering as an observer. Then you can write your observeValueForKeyPath method like



- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id) object change:(NSDictionary *)change context:(void *)context
{
// NSLog( @">>>> Detected Change in keyPath: %@", keyPath );
if ([[change objectForKey:NSKeyValueChangeNotificationIsPriorKey] boolValue] == YES) {
[self willChangeValueForKey:keyPath];
} else {
[self didChangeValueForKey:keyPath];
}
}



2) Cache the old value in the object and don't use any of the KVO options. This is the one I like the most.



static NSString *NoValueMarker = @"NoValueMarker"; static NSString *NilValueMarker = @"NilValueMarker";

- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id) object change:(NSDictionary *)change context:(void *)context
{
// NSLog( @">>>> Detected Change in keyPath: %@", keyPath );
[self willChangeValueForKey:keyPath];
[observedKeys setObject:NoValueMarker forKey:keyPath];
[self didChangeValueForKey:keyPath];
}


-(id)valueForUndefinedKey:(NSString*)key {
    id result = [observedKeys objectForKey:key];

    if (result == nil) {
        [obj addObserver:self forKeyPath:key options:0 context:nil];
    }

    if ((result == nil) || (result == NoValueMarker)) {
        result = [obj valueForKey:key];

        if (result != nil) {
            [observedKeys setObject:result forKey:key];
        } else {
            [observedKeys setObject:NilValueMarker forKey:key];
        }
    }

    if (result == NilValueMarker) {
        result = nil;
    }

    return result;
}




-------------------------- RONZILLA



_______________________________________________

Cocoa-dev mailing list (email@hidden)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden


References: 
 >Implementing a KVO/Bindings-Compliant Bridge-Pattern in Cocoa (From: "Sebastian Morawietz" <email@hidden>)

  • Prev by Date: Cocoa / OC exception handlng - answered
  • Next by Date: Re: Objective 2.0 properties
  • Previous by thread: Re: Implementing a KVO/Bindings-Compliant Bridge-Pattern in Cocoa
  • Next by thread: Re: executables for OSX 10.4 vs 10.5
  • Index(es):
    • Date
    • Thread