Core Data Transient Calculated Attributes
Asked Answered
F

1

7

I have an entity that contains lastName and firstName attributes. For reasons beyond the scope of this question, I want a fullName attribute that gets calculated as a concatenation of firstName + space + lastName.

Because this is purely a calculated value, with no need for redo/undo or any other of the more sophisticated aspects of transient attributes (merging, etc.), my gut tells me to just override the getter method to return said calculated value. Reading suggests that, if I do this, my only concern would be whether it's KVO compliant, which I can address by using keyPathsForValuesAffectingVolume to ensure changes to firstName or lastName trigger notifications for anyone observing on fullName.

Am I missing anything? I'm checking because I'm a beginner to this environment.

Florindaflorine answered 17/5, 2011 at 16:38 Comment(0)
J
2

I'm also new to this, so I'm not completely sure about my answer, but as I understand it you are correct.

- (NSString *)fullName
{
    [self willAccessValueForKey:@"fullName"];
    NSString *tmp = [self primitiveFullName];
    [self didAccessValueForKey:@"fullName"];

    if (!tmp) {
        tmp = [NSString stringWithFormat:@"%@ %@", [self firstName], [self lastName]];
        [self setPrimitiveFullName:tmp];
    }
    return tmp;
}

- (void)setFirstName:(NSString *)aFirstName
{
    [self willChangeValueForKey:@"firstName"];
    [self setPrimitiveFirstName:aFirstName];
    [self didChangeValueForKey:@"firstName"];

    [self setPrimitiveFullName:nil];
}

- (void)setLastName:(NSString *)aLastName
{
    [self willChangeValueForKey:@"lastName"];
    [self setPrimitiveLastName:aLastName];
    [self didChangeValueForKey:@"lastName"];

    [self setPrimitiveFullName:nil];
}

+ (NSSet *)keyPathsForValuesAffectingFullName
{
    return [NSSet setWithObjects:@"firstName", @"lastName", nil];
}
Joycelynjoye answered 17/5, 2011 at 18:5 Comment(4)
Hi Mark. Thanks for responding. My only question has to do with your calls to [self primitiveFullName:nil] and [self primitiveFullName: tmp]. If the only way a user can access your value is through your getter, and the getter always returns the correct value, why do you concern yourself with what is being stored for the transient property? Please note, I suspect you're absolutely correct in doing so...I'm just fishing to see if I'm missing some subtlety to all this.Florindaflorine
Hi Mark. Also, out of curiosity, why are you able to use the form: [self setPrimitiveFirstName:aFirstName] for setting the primitive value, whereas I'm forced to use the form: [self setPrimitiveValue:aFirstName forKey:@"firstName"]? Again, just fishing!Florindaflorine
Whoops. Didn't realize that I was using primitiveFullName: instead of setPrimitiveFullName:Joycelynjoye
Actually, I didn't have a complaint with your code. I was wondering if, despite generating NSManagedObject classes from Core Data's modeling tool (i.e. with the proper use of @property, @dynamic, etc., in the generated class), you'd ever received the "Method not found" message when attempting to use the setPrimitive<key> method vs the setPrimitiveValue:forKey: method. I have two entity classes generated from the same model; I can't tell any difference between them; yet one permits the use of the more efficient method; the other does not.Florindaflorine

© 2022 - 2024 — McMap. All rights reserved.