Ever since Leopard came out, I’ve wanted to do something useful with
resolveInstanceMethod:. The opportunity has yet to present itself. However, I have done a couple of really silly things with it, which have until now languished in obscurity in the depths of paste.lisp.org. So here they are.
This allows you to use arbitrary accessors on dictionaries, or arbitrary properties if you declare them first (no definition necessary). Example:
@interface NSDictionary (MyProperties) @property (retain) NSString *fruit; @end ... NSMutableDictionary *myDict = [NSMutableDictionary dictionary]; dict.fruit = @"apple"; // -setFruit: method is generated dynamically.
This defines a new string concatenation operator,
:. Well, almost. It allows you to append any number of strings (or arbitrary object descriptions) to a string using the following syntax:
[@"string " : @"other string " : arbitraryObject : @" yet another string "]
Unfortunately, a header is required in this case to avoid unknown selector warnings.
As noted in each of the files, I don’t recommend actually using these. They’re exercises in understanding the mechanics of the language rather than actually useful utilities. In particular, if you use Easy Dictionary you’re in for a world of hurt when you try to use a property that
NSDictionary already has, like
I do enjoy runtime hackery.
Though I think there’s a slight mistake in the comment on Easy Dictionary, isn’t it -setFruit: which is dynamically generated?
I wouldn’t be so quick to discount using the code either, I typically prototype things in NSDictionary and use my version of this code to synthesize virtual assessors. So when I swap that dictionary out for a bona fide model object I just have to copy and paste the property declarations and include the synthesize directive. That way client code will work with zero changes, it’s as if nothing changed.
I look forward to working on 64 bit only when the instance variables are synthesized automatically too.
You are quite right, -setFruit: it is.
For a rather dramatic extension of this idea (that also uses +resolveInstanceMethod), have a look at RMModelObject. There are some problems with it and it’s not quite complete, but it’s good enough that we’re actually using it in production :).
I haven’t looked at it in detail, but the first thing I like about RMModelObject compared to my quick hack is that it isn’t NSDictionary. :-) Using +resolveInstanceMethod for automatic model objects and mock objects is well and good, but I still don’t think using it on any old dictionary is a great idea. (Has-a vs. is-a releationships, and all that.)