Core Data and transient properties

7.2k views Asked by At

I'm having trouble with setting up a transient property in Core Data. The problem I'm trying to solve is: I have a collection of objects successfully stored using Core Data. This collection is essentially a read-only collection but at run-time, I want to associate another object (a UIImage in this case) with each item in the collection. I do not need to store the UIImages; it is purely a run-time association. So what I really need is a 'placeholder' in each object in the collection where I can drop the UIImage later.

A transient attribute seems like the right thing and, for this, Core Data reference docs tell me that I should set up an "optional, transient attribute of type undefined" in the data model which I have done: XCode snippet

Further, it tells me that I do not need to define a corresponding property in the implementation object but that I will have to write custom accessor & setter methods. I've modeled these methods based on the examples in the docs as follows:

- (void)setDisplayImage:(UIImage *)anImage {

    [self willChangeValueForKey:@"displayImage"];
    [self setPrimitiveValue:anImage forKey:@"displayImage"];
    [self didChangeValueForKey:@"displayImage"];
}

and:

- (UIImage *)displayImage {

    [self willAccessValueForKey:@"displayImage"];
    UIImage *anImage = [self primitiveDisplayImage];
    [self didAccessValueForKey:@"displayImage"];

    if (anImage == nil) {       
        NSData *displayImageData = [self displayImageData];
        if (displayImageData != nil) {
            anImage = [NSKeyedUnarchiver unarchiveObjectWithData:displayImageData];
            [self setPrimitiveDisplayImage:anImage];
        }
    }
    return anImage;
}

There is also a deferred "write" method (willSave) that I have written for strict completeness although, as above, I will never be writing these objects back to store.

The problem I am getting is in the primitiveDisplayImage and setPrimitiveDisplayImage methods of - (UIImage *)displayImage { . Basically, the compiler throws warnings on these two methods as "object X may not respond to 'primitiveDisplayImage'.." etc. However, my understanding from the docs is that these primitive accessors/setters ARE created automatically - this does not seem to be the case. Anyone out there who can help me solve this issue? Many thanks

2

There are 2 answers

0
Marc Charbonneau On

The problem with setPrimitive... methods is that although NSManagedObject will respond to them at runtime, the compiler has no way of knowing they exist. You can suppress the warning messages by declaring the method in your entity class's header file, using a category so the compiler doesn't yell at you for not defining it in your implementation.

Another option is just using calling [self setPrimitiveValue:value forKey:@"key"]; for each of the attributes you need to access. I've used this method in the past, although I just noticed in the docs that this is discouraged on 10.5 and later.

0
TimCinel On

Found the answer here: Managed Object Accessor Methods

Basically: Declare @propery in category header file, define @dynamic in category implementation file.