Maybe this could be a start:
@interface NSObject (LazyKVC)
- (id)lazyValueForKey:(NSString *)key;
@end
@implementation NSObject (LazyKVC)
- (id)lazyValueForKey:(NSString *)key {
id value = [self valueForKey:key];
if (!value) {
// Now, look for the type of property named |key|.
// To spare you the details of the @encode() string, use
// [self typeOfPropertyNamed:key] - see link provided below
NSString className = [NSString stringWithUTF8String:
[self typeOfPropertyNamed:key]];
Class propertyClass = NSClassFromString(className);
if (propertyClass) {
value = [[propertyClass alloc] init];
}
}
return value;
}
@end
Note:
- The code above uses
- (const char *)typeOfPropertyNamed:(NSString *)name
, available here.
- I omitted corner cases (dealing with errors, etc.).
Usage would be:
[foo lazyValueForKey:@"bar"];
I'm curious if you can make it work like that (I wrote this in the browser window directly...)
Note about (dependency) injection
In order for your method to be able to return the object you want at runtime (via injection) you would need - as a starting point - the following:
- a configuration file (to tell
lazyValueForKey:
where to initialize the injected object from, e.g. a plist)
- a convention: how will you name that configuration file so
lazyValueForKey:
will find it
- a method that will enable you to lookup and initialize an object from a configuration file (e.g. what fields and attributes will you include in your configuration file to describe objects).
- modify the
lazyValueForKey:
method to effectively de-serialize/read objects from the configuration file
Note that points 1-2-3 above could further lead you to abstract a dependency injection data source that would manage the configuration of your injected objects and provide you with them at runtime.
I am certainly missing other important points here, but I believe this is starting to get out of the scope of your original question, so I won't go any further with my answer. Implementing a dependency injection mechanism is no easy feat. However, you might find more info at this nice SO question.