On 01/02/2013, at 5:18 PM, Quincey Morris <quinceymor...@rivergatesoftware.com> 
wrote:

>> /* CoreGraphics - CGPath.h
>>    Copyright (c) 2001-2011 Apple Inc.
>>    All rights reserved. */
>> 
>> typedef struct CGPath *CGMutablePathRef;
>> typedef const struct CGPath *CGPathRef;
> 
> So KVC isn't going to know these are objects. Interestingly, types like 
> 'dispatch_semaphore_t' aren't declared this way, so they probably *do* work 
> via 'valueForKey:' without assistance.


Aha... that is probably what's going on. I wonder why these aren't typedef'd as 
CFTypeRef?

Anyway, as long as I'm aware of the problem with KVC, and can rely on it 
hitting -valueForUndefinedKey:, a fairly general solution isn't that bad.

I'm mostly interested in using KVC here for automatically archiving without 
having to write hundreds of lines of code of the kind [encoder 
encodeObject:<blah> forKey:<bleh>];

Those objects that can take advantage of this inherit from a simple base class 
which exports one public class method, +archivableProperties, returning a NSSet 
of keys. By doing this rather than using runtime introspection to find all the 
properties allows objects to only specify those that they want to auto-archive, 
and others can be ignored or handled as a special case if needed. Then, this 
same base class implements default -initWithCoder and encodeWithCoder: methods 
that iterate these keys using KVC to get and set the property values.

For the errant CFTypes, I hit -valueForUndefinedKey: and 
-setValue:forUndefinedKey:, overridden in this base class. This then checks 
whether in fact the selector really is undefined, and if not, it forces the 
value to be returned using -performSelector. It then passes off these CFTypes 
to some conversion utilities that, for each type of interest, grabs all the 
necessary values and puts them into a dictionary, and returns that. The 
dictionary of course can be archived. On dearchiving, I simply reverse the 
process, building new CFType objects from the dictionaries.

If an object wants to override -initWithCoder and -encodeWithCoder and do 
things the long-winded way, it can do so and will still work, it just needs to 
not return those properties in +archivableProperties.

The goal of all this was so that each subclass only needs to override 
+archivableProperties and return the combined list of super's property keys and 
its own, and will be fully archivable with no more work, even if the properties 
run into many dozens (as they do), and are mostly of CFTypes (as they often 
are). In addition it must eventually work on iOS, which is why I'm avoiding 
certain objects in favour of CFTypes, e.g. CGColorRef rather than NSColor.


--Graham


_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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

This email sent to arch...@mail-archive.com

Reply via email to