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: motti.shn...@gmail.com phone: +972-8-9267730 mobile: +972-54-3136621 ---------------------------------------- Ceterum censeo Microsoftinem delendam esse _______________________________________________ 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