Re: How to implement an object whose properties are really dictionary entries.
Re: How to implement an object whose properties are really dictionary entries.
- Subject: Re: How to implement an object whose properties are really dictionary entries.
- From: Motti Shneor <email@hidden>
- Date: Thu, 12 Jul 2012 12:32:48 +0300
Thanks Quincey. I seem to have missed that one.
I already have dealt with forwardInvocation, in another class (some kind of NSNotificationCenter replacement which dispatches messages to registered objects, in prioritized and synchronized way). I think I can do it without much hassle. This covers things like [myObject firstName] in addition to myObject.firstName, and [myObject setFirstName] in addition to myObject.firstName = @"xxx";
I do not intend to forward the invocation at all, rather to parse it, and call my internal general-purpose setter/getter method.
I completely forgot about "respondsToSelecor:" but here, again, it can be done --- only I hate to implement cocoa's naming convention myself (knowing I have a key like "firstName", to respond to a @selector(setFirstName:). Isn't the machinery for that part of the runtime? Who implements those naming conventions?
On 12 ביול 2012, at 10:59, Quincey Morris wrote:
> On Jul 12, 2012, at 00:14 , Motti Shneor wrote:
>
>> On 12 ביול 2012, at 02:54, Keary Suska wrote:
>>
>>> On Jul 11, 2012, at 2:45 PM, Motti Shneor wrote:
>>>> Of what I read from everyone, and after examining the suggested code from Jens Alfke, I think I'm inclined to something simpler, hinted by Keary Suska. Could you spare a few more words on the "undefinedKey" override?
>>>
>>> I would create a base class that implements -valueForUndefinedKey: and -setValue:forUndefinedKey: (per the doc links that another poster provided). These methods would simply get/set from the dictionary. The only thing that requires a little consideration is how you may choose to validate the key (if at all)--i.e. determine whether you want to throw an exception for unknown keys. You can throw by simply calling super's implementation. To validate you could keep an array of valid key names (somewhat fragile, as you need to keep it updated), or use runtime inspection functions (see:https://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtPropertyIntrospection.html#//apple_ref/doc/uid/TP40008048-CH101-SW24). More cryptic but not fragile.
>>>
>>
>> Thanks, I think this is exactly what I was looking for.
>>
>> In my case it is almost trivial. These classes maintain dictionaries to convert from the class' Keys (properties) to the base-model (CoreData) attribute names in the schema. I can simply look up the internal key, and throw (via super implementation of valueForUndefinedKey/setValue:forUndefinedKey) if I can't find it.
>>
>> If I'm going this route, do I still need to use the @dynamic for my properties? after all --- promised implementations wont be available in runtime. I rely on a KVO pre-exception mechanism.
>
> Maybe I haven't been following this closely enough, but you and Keary seem to be talking at cross purposes.
>
> -- If you *do* want to call property accessors in clients of your class, then the KVC method such as 'valueForUndefinedKey:' are of no use to you, because the accessors don't go through KVC. (It's the other way round -- KVC will call the accessors if they exist.)
>
> In this case, I think you should take a look at 'forwardInvocation:', documented here:
>
> https://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtForwarding.html#//apple_ref/doc/uid/TP40008048-CH105-SW1
>
> Note that you can't actually forward the invocation as is, since there's no implementation of the relevant methods anywhere, but notice the comment that "A forwardInvocation: method can act as a distribution center for unrecognized messages, … . It can translate one message into another, …". In other words, you'll have to detect/validate the selector/parameter pattern in the invocation, then modify or recreate the invocation to refer to a pair of methods that do the actual work. None of this should be very hard, since there are only 2 selector patterns to detect.
>
> This technique would avoid mucking about with the runtime class information directly (which you seem reluctant to do).
>
> The only issues I see are:
>
> a. I think you'll need to override 'respondsToSelector:' as well as 'forwardInvocation:', so that KVC will think that your dynamic accessors exist.
>
> b. This all depends on knowing whether property names are valid, but you say that you know that without having to add any data structures to your class implementation. You'll just have to define the properties as '@dynamic' to keep the compiler from complaining.
>
> If you're not willing (or able, for some reason I haven't foreseen) to use an approach like this, I think Dave's suggestion of macros is your best solution, although it's a little bit ugly at the source code level.
>
> -- If you *don't* want to call property accessors in clients of your class, but use the class only for (e.g.) bindings or other things that use KVC, then 'valueForUndefinedKey:' etc. is the right way to go.
>
>
Motti Shneor
e-mail: email@hidden
phone: +972-8-9267730
mobile: +972-54-3136621
----------------------------------------
Ceterum censeo Microsoftinem delendam esse
_______________________________________________
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