nicklockwood / AutoCoding

AutoCoding is a category on NSObject that provides automatic support for NSCoding and NSCopying to every object.
Other
1.07k stars 131 forks source link

BaseModel integration #15

Open mrtristan opened 10 years ago

mrtristan commented 10 years ago

my class extends BaseModel but i'd like it to implement NSCopying so I'm also now importing AutoCoding. because BaseModel has an uncodableProperties class method, AutoCoding is spitting out a whole ton of

AutoCoding Warning: uncodableProperties method is no longer supported. Use ivars, or synthesize your properties using non-KVC-compliant names to avoid coding them instead.

Is there a more appropriate way to implement NSCopying or should I be doing something differently? I don't have any "uncodable" properties in my classes.

thanks for these awesome classes :-)

nicklockwood commented 10 years ago

Yes, you can easily implement NSCopying yourself in a subclass of BaseModel, without using AutoCoding. Just add this method to your class:

- (id)copyWithZone:(id)zone
{
    id copy = [[[self class] alloc] init];
    for (NSString *key in [self codablePropertyKeys])
    {
        [copy setValue:[self valueForKey:key] forKey:key];
    }
    return copy;
}
mrtristan commented 10 years ago

so i'd like your opinion on something. i have a complex stack of objects that all extend from my base class that extends BaseModel. i'd like them all to conform to NSCopying so i implemented what you suggested in my 'base' BaseModel extension.

first thing, codablePropertyKeys is a class method and not an instance method so i made a slight tweak to your suggestion. my question is, do you think the following bit of logic is necessary for recursive purposes so that all of my BaseModel class extensions that are inside my outer object that I attempt to copy are handled or do you think that it isn't needed?

your suggestion, tweaked:

-(id)copyWithZone:(NSZone *)zone {
    id copy = [[[self class] alloc] init];
    for (NSString *key in [[self class] codablePropertyKeys]) {
        [copy setValue:[self valueForKey:key] forKey:key];
    }
    return copy;
}

some potentially extraneous logic:

-(id)copyWithZone:(NSZone *)zone {
    id copy = [[[self class] alloc] init];
    for (NSString *key in [[self class] codablePropertyKeys]) {
        if([[self valueForKey:key] respondsToSelector:@selector(copyWithZone:)]) {
            [copy setValue:[[self valueForKey:key] copyWithZone:zone] forKey:key];
        }else {
            [copy setValue:[self valueForKey:key] forKey:key];
        }
    }
    return copy;
}