Re: CORE DATA: setImage (transient) and setImageData (binary) accessors don't fire.

  • > On Jan 15, 2006, at 12:45 AM, Frederick C. Lee wrote:
    >> Specifically, the 'setImageData' accessor isn't firing.
    >>
    >> I don't know why.
    >
    >
    > One possibility is that in your data model, you haven't specified the
    > entity's class but rather left it at the default value of
    > NSManagedObject. If you don't specify this, it will go right to
    > valueForKey: and setValue:forKey: and not use your accessors

    I checked the code and re-affirmed that the Map entity is correctly
    defined by the 'MapManagedObject'
    subclass.  The other entities are 'NSManagedObjects'.

    The 'MapManagedObject' has the added 'setImage' and 'setImageData'
    accessors.

    Just for the sake of confirmation of my problem, I changed
    'imageData' datatype from binary to string,
    disconnected the NSImageView and placed a NSTextField in the GUI and
    bind it to 'imageData'.

    Sure enough, 'setImageData' fired.

    When I return to the original configuration, 'setImageData' did NOT
    Fire.

    Then I changed the binding of the NSImageView from 'view' to
    'data'.  And bind it directly to
    'imageData' binary (vs 'image' transient).  Again, 'setImage' and
    'setImageData' did NOT fire.

    So there's something about being a non-string here, that doesn't
    allow the SET accessor to fire.
    That's the problem.
    And so far, I can't figure it out.

    So the question is, how does NSManagedObject effect binary accessors
    differently from strings??
    Any clues, suggestions....remedies?
  • On Jan 15, 2006, at 9:49 AM, Frederick C. Lee wrote:

    > So the question is, how does NSManagedObject effect binary
    > accessors differently from strings??

    It doesn't.

    > [AppDelegate] -->> [RegionArrayController -->> [MapArrayController]
    > --->> NSImageView GUI.  *problem*
    > ...appears to be a bug: too complicated for binding.
    >
    It is almost certainly a bug in your set-up.

    You seem to be making this extraordinarily complicated.

    Please, just create a simple project with a single Entity, Person.

    Add two attributes:
    name: String
    imageData: Binary

    If you want, create a custom class for the entity (directly from
    Xcode using the New File menu item), and put a log statement in the
    setImage: method.  In the subsequent test, it *will* be called.

    Now "auto-create" an interface for Many Objects.  Amongst other
    things, you get an image view, properly configured for the image
    attribute for the selected Person object.

    You should get a complete working application that allows you to add
    Person objects, give them names, and drop images into the image view.

    Check the bindings for the image view, and make sure your interface
    matches.

    If you really need to store a separate NSImage, then to the Person
    entity add another attribute,

    nsImage: Undefined (Transient).

    Then implement the accessor methods etc. as shown in the Core Data
    Programming Guide (see below).

    Finally, change the binding of the image view:
    (1) Unbind 'data'.
    (2) Bind 'value' to [Person Array Controller].selection.nsImage

    mmalc

    - (NSImage *)nsImage;
    {
        [self willAccessValueForKey:@"nsImage"];
        NSImage *image = [self primitiveValueForKey:@"nsImage"];
        [self didAccessValueForKey:@"nsImage"];
        if (image == nil) {
            NSData *imageData = [self valueForKey:@"imageData"];
            if (imageData != nil) {
                image = [[[NSImage alloc] initWithData:imageData]
    autorelease];
                [self setPrimitiveValue:image forKey:@"nsImage"];
            }
        }
        return image;
    }

    - (void)setNsImage:(NSImage *)value
    {
        [self willChangeValueForKey: @"nsImage"];
        [self setPrimitiveValue: value forKey: @"nsImage"];
        [self didChangeValueForKey: @"nsImage"];
    }

    - (void)willSave
    {
        NSImage *image = [self primitiveValueForKey:@"nsImage"];
        if (image != nil) {
            [self setPrimitiveValue:[image TIFFRepresentation]
    forKey:@"imageData"];
        }
        else {
            [self setPrimitiveValue:nil forKey:@"imageData"];
        }
        [super willSave];
    }

    (Note: This assumes that you will always access the image using the
    NSImage object.  If you change the image object, the NSData object is
    not synchnronised until save time.)
previous month january 2006 next month
MTWTFSS
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31          
Go to today