On 12/11/2010, at 8:45 PM, Remco Poelstra wrote:

> If I ommit the valueForKey method, how does the KVC logic now, that it should 
> check the properties variable?
> Further more, NSDictionary seems to always return a value, so all keys are 
> "defined", they just return nil sometimes. How can valueForUndefinedKey: then 
> ever be called?


nil from NSDictionary means no value associated with the key (dictionaries 
cannot store 'nil' as a value) so this is your cue to go fetch. The problem is 
that the object on which -valueForUndefinedKey: is invoked is the dictionary, 
not your wrapper, and since you are not subclassing the dictionary, you won't 
get that message (and the default will simply throw an exception). So instead, 
the override to -valueForKey: in your wrapper is acceptable, in this case. But 
instead of invoking -valueForKey: on the dictionary, use -objectForKey: 
directly. That way, you get nil when there's no key instead of an exception.

 If you have properties that can legally be nil, you'll need to treat those 
differently, using some sort of marker object that means the property really 
should return nil (and hence can be stored in a dictionary). For example 
[NSNull null] is a valid object which means 'nil'. Basically, you can't use nil 
itself to mean two different things, both uninitialized and a legal value, and 
since NSDictionary reserves the use of nil to mean undefined, you have no 
choice but to deal with that in some way.

@implementation MyWrapper

- (id)  valueForKey:(NSString*) key
{
        id value = [myDictionary objectForKey:key];     

        if( value )
                return value;

        [self beginFetchForKey:key];    // assume starts a thread or 
asynchronous task which calls -setValue:forKey: on completion

        return nil;                     // OK, we have no value to return yet.
}


- (void) setNilValueForKey:(NSString*) key
{
     [myDictionary setObject:[NSNull null] forKey:key]; // substitute a valid 
object for nil values
}


Because this does not override -setValue:forKey: you get all the usual goodness 
that gives you, such as KVO notifications. As your thread sets the value using 
KVC any observers get notified of the value having been fetched automatically 
(if you are using a thread take care to set the value on the main thread so 
that all notifications take place on the main thread).

The override to -valueForKey: here does lose some of the 'special powers' that 
Ken alluded to, one of them being the treatment of a leading '@' in the key. If 
that matters, you need to emulate what NSDictionary's implementation does. But 
since you are really replacing NSDictionary's version with your own, which has 
already discarded the vast majority of NSObject's 'special powers' I can't see 
you are losing much in this case. It has the advantage that subclassing 
NS(Mutable)Dictionary is not required.

--Graham




_______________________________________________

Cocoa-dev mailing list ([email protected])

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [email protected]

Reply via email to