HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

NSManagedObject in need of smart setters

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
smartnsmanagedobjectsettersneed

Problem

I'm just beginning my foray into iOS development and need a code review. I have a custom NSManagedObject that needs some smart setters. I'm new to Objective-C, iOS, and core-data development, so I don't trust myself yet. I come from a Java background, so smart setters are what I know, but might not be best when using Core Data.

+(void)initialize
{
    scoredKeys = @[@"fullSwings", @"putts", @"fairwayBunkers", @"greenBunkers", @"chipsOrPitches", @"rescue", @"wastedOrPenalty"];
}

-(id) initWithHoleNumber:(int)holeNumber
{
    self = [super init];
    if (self) {
        [self setHoleNumber:[NSNumber numberWithInt:holeNumber]];
    }
    return self;
}

-(void) incrementItem:(NSString *)key
{
    [self willAccessValueForKey:key];
    NSNumber *value = [self primitiveValueForKey:key];
    int intValue = value.intValue;
    [self didAccessValueForKey:key];

    [self willChangeValueForKey:key];
    [self setPrimitiveValue:[NSNumber numberWithInt: intValue++] forKey:key];
    [self didChangeValueForKey:key];

    [self recalculateScore];
}

-(void) recalculateScore
{
    NSString *key;
    NSNumber *current;
    int tally = 0;

    for (key in scoredKeys) {
        [self willAccessValueForKey:key];
        current = [self primitiveValueForKey:key];
        tally = tally + current.intValue;
        [self didAccessValueForKey:key];
    }

    [self willChangeValueForKey:@"score"];
    [self setPrimitiveValue:[NSNumber numberWithInt:tally] forKey:@"score"];
    [self didChangeValueForKey:@"score"];
}


I am also seeking general comments about my approach.

  • In the core-data docs, it says the auto generated accessors are much faster than anything a developer can write, so is this a good idea?



  • Should I not even have a score property, and just have a method that returns the tally?

Solution

without referring to your code, I think there is one pattern, that makes core data more fun but sadly isnt supported by Xcode out-of-the-box:

Have two classes for each model: one for automatic code generation — it will be jsut changed by Xcode — and on that inherits from the first, that can be changed and will never touched again by the machine after creation.

// for the machine
@class _Event : NSManagedObject
@end

// for human beings
@class Event : _Event
// what ever you need: put it here
@end


a great tool to teach Xcode this pattern is mogenerator. mogenerator + Xcode4.x

Another similar approach would be to have categories on the Model class. But this is less powerful and needs more attention for importing.

Now to your code.

I dont see any reason to overwrite the setter. if apple says that you most likely will never be able to write as performant accessors as the provide, they probably are right. Instead you should create your own method, that will set up a object as need. you could overwrite save and similar methods, or access it via a wrapper class, that will set it up for you.


I plan to create a service class as a factory that manages the entities and their interactions with the context.

that sounds valid and could be the wrapper class mentioned above. But make sure, you create the model objects with initWithEntity:insertIntoManagedObjectContext:, as you want them in your context.

Core Data is a great and powerful framework. but beware: if you shoot yourself in the foot, most likely both your legs will be gone.

2 Years ago I was working in a team where the Engineer responsible for persistency accidentally overwrote an internal method of NSManagedObject. It took him one week to find the cause and fix it by renaming his method. This line of code was probably the most expensive in the whole project. There-for another hint: prefix your custom methods.

Code Snippets

// for the machine
@class _Event : NSManagedObject
@end

// for human beings
@class Event : _Event
// what ever you need: put it here
@end

Context

StackExchange Code Review Q#20634, answer score: 3

Revisions (0)

No revisions yet.