views:

357

answers:

2

I have a feeling that this is stupid question, but I'll ask anyway...

I have a collection of NSDictionary objects whose key/value pairs correspond to a custom class I've created, call it MyClass. Is there an easy or "best practice" method for me to basically do something like MyClass * instance = [ map NSDictionary properties to MyClass ];? I have a feeling I need to do something with NSCoding or NSKeyedUnarchiver, but rather than stumble through it on my own, I figure someone out there might be able to point me in the right direction.

+2  A: 

Assuming that your class conforms to the Key-Value Coding protocol, you could use the following: (defined as a category on NSDictionary for convenience):

// myNSDictionaryCategory.h:
@interface NSDictionary (myCategory)
- (void)mapPropertiesToObject:(id)instance
@end


// myNSDictionaryCategory.m:
- (void)mapPropertiesToObject:(id)instance
{
    for (NSString * propertyKey in [self allKeys])
    {
        [instance setValue:[self objectForKey:propertyKey]
                    forKey:propertyKey];
    }
}

And here's how you would use it:

#import "myNSDictionaryCategory.h"
//...
[someDictionary mapPropertiesToObject:someObject];
e.James
Thank you. This was what I was looking for. :)
LucasTizma
You're welcome!
e.James
Looks like Red has an even better answer. I recommend you switch the accepted answer to his :)
e.James
Done. :) Nevertheless, your answer was helpful for getting me thinking about how this needs to be done.
LucasTizma
+6  A: 

The -setValuesForKeysWithDictionary: method, along with -dictionaryWithValuesForKeys:, is what you want to use.

Example:

// In your custom class
+ (id)customClassWithProperties:(NSDictionary *)properties {
   return [[[self alloc] initWithProperties:properties] autorelease];
}

- (id)initWithProperties:(NSDictionary *)properties {
   if (self = [self init]) {
      [self setValuesForKeysWithDictionary:dictionary];
   }
   return self;
}

// ...and to easily derive the dictionary
NSDictionary *properties = [anObject dictionaryWithValuesForKeys:[anObject allKeys]];
retainCount
That's pretty handy, and setValuesForPropertiesWithKeys is the way to go. It does exactly what my code does, and it's built in! Nice find.
e.James
It's a wonderful method. Using that in conjunction with the objc_* API, you can build an auto-serializing class (so you can stop writing those cumbersome -initWithCoder: and -encodeWithCoder: methods)
retainCount
Awesome. That's going to come in handy.
e.James
@Red: Thank you! Yeah, I was hoping to find a "all in one" way to do this succinctly. Could you elaborate or point to something that explains more about the objc_* API?
LucasTizma
retainCount