What should be the same object doesn't seem to be

  • Hi there-

    I have a problem where the object that I choose from a contextual
    menu that I custom-build does not seem to be the same object that is
    later chosen from that menu by the user. Additionally, it makes me
    wonder if I'm making a mistake in my way of thinking about how I'm
    doing things on a larger scale.

    This is a scheduling program. What is happening is that the user is
    right-clicking on a graphical representation of what I call an
    "OrderStep" to choose what type of operation (OperationType) is
    required to perform the work on the OrderStep.

    First I build the contextual menu in a menuNeedsUpdate method like
    this: (note that I use representedObject to link the menu item to the
    corresponding operationType)

    //first, remove all items except for the last 2 (which are "edit..."
    and the separator line)
    int loop;
    for (loop = [menu numberOfItems] - 3; loop >= 0; loop--)
    {
    [menu removeItemAtIndex:loop];
    }

    //sort the array
    NSSortDescriptor *descriptor = [[[NSSortDescriptor alloc]
    initWithKey:@"operationTypeCode" ascending:YES] autorelease];
    NSArray *descriptors = [NSArray arrayWithObjects:descriptor, nil];
    [operationTypes sortUsingDescriptors:descriptors];

    //now rebuild the menu with the items from operationTypes
    NSMenuItem *menuItem;
    for (loop = [operationTypes count] - 1; loop >= 0; loop--)
    {
    menuItem = [menu insertItemWithTitle:[[[self operationTypes]
    objectAtIndex:loop] operationTypeName]
          action:@selector(operationTypeWasSelected:)
          keyEquivalent:@""
          atIndex:0];
    //set the represented object of this new menu item to be the
    appropriate operation type
    [menuItem setRepresentedObject:[operationTypes objectAtIndex:loop]];

    }

    Then, when the user goes to assign an operationType from the above
    menu to what I call an "OrderStep", this gets called (by the action:
    specified above):

    //called by the user selecting an operation type from the submenu
    - (void)operationTypeWasSelected:(NSMenuItem *)menuItem;
    {
    NSLog(@"The operation was selected! %@", [menuItem representedObject]);
    [[self clickedObject] setOperationType:[menuItem representedObject]];

    [stepView setNeedsDisplay:YES];
    }

    The problem is that even though the selection of the OperationType
    from the menu seems to go just fine (for instance, the correct
    information appears, showing the correct operation name on the
    OrderStep), it appears that the OperationType object is actually not
    the same object that was attached to the menu, but seems to be a copy
    of it or something. If I compare them, I see that one of them might
    be 0x3c8fe0 and the other might be 0x3d2bd0 (what are these? they
    seem too short to be pointers to the objects)

    The reason i have to compare them is to see if a given WorkCenter can
    perform the work required by the OrderStep. The problem is that the
    WorkCenter's OperationType (the type of work it can do) object is not
    the same as the OrderStep's OperationType (the type of work it needs
    done) even though to my mind they should be exactly the same.

    I'm afraid I have poorly presented this, but it's my best at this
    time. If anyone can throw any ideas my way, I'm very grateful.

    Maybe I shouldn't be comparing the actual objects, but instead I
    should be comparing something more basic held within the object (each
    OperationType has an operationTypeCode which is an Int to give the
    user a numeric representation of the operation type). Maybe I should
    compare that?
  • On 2 Oct 2007, at 9:39 AM, Paul Bruneau wrote:

    > //now rebuild the menu with the items from operationTypes
    > NSMenuItem *menuItem;
    > for (loop = [operationTypes count] - 1; loop >= 0; loop--)
    > {
    > menuItem = [menu insertItemWithTitle:[[[self operationTypes]
    > objectAtIndex:loop] operationTypeName]
    > action:@selector(operationTypeWasSelected:)
    > keyEquivalent:@""
    > atIndex:0];
    > //set the represented object of this new menu item to be the
    > appropriate operation type
    > [menuItem setRepresentedObject:[operationTypes objectAtIndex:loop]];
    >
    > }
    >
    >
    > Then, when the user goes to assign an operationType from the above
    > menu to what I call an "OrderStep", this gets called (by the action:
    > specified above):
    >
    > //called by the user selecting an operation type from the submenu
    > - (void)operationTypeWasSelected:(NSMenuItem *)menuItem;
    > {
    > NSLog(@"The operation was selected! %@", [menuItem
    > representedObject]);
    > [[self clickedObject] setOperationType:[menuItem representedObject]];
    >
    > [stepView setNeedsDisplay:YES];
    > }
    >
    > The problem is that even though the selection of the OperationType
    > from the menu seems to go just fine (for instance, the correct
    > information appears, showing the correct operation name on the
    > OrderStep), it appears that the OperationType object is actually not
    > the same object that was attached to the menu, but seems to be a
    > copy of it or something. If I compare them, I see that one of them
    > might be 0x3c8fe0 and the other might be 0x3d2bd0 (what are these?
    > they seem too short to be pointers to the objects)

    The first question to ask is whether the inserted object is really not
    the same as the selected object. Your sample code shows you log the
    selected object, but not that you log the inserted object (just before
    or after setRepresentedObject:).

    The string representation of pointers is done through a format like
    "%x", which would suppress leading zeroes in the address. Your
    pointers don't look wrong to me.

    — F
  • On Oct 2, 2007, at 11:48 AM, Fritz Anderson wrote:

    > The first question to ask is whether the inserted object is really
    > not the same as the selected object. Your sample code shows you log
    > the selected object, but not that you log the inserted object (just
    > before or after setRepresentedObject:).

    I greatly appreciate your response.  In fact I have verified that the
    object is the same there. Some more digging has let me find where the
    objects differ and it was in a part that I didn't discuss very well
    if at all in my original post.

    Where the (unfortunately) different OperationType objects are getting
    created is the part of the interface where I let the user select
    which OperationTypes a WorkCenter is (are) able to perform. I am
    using an IB window and bindings with a "master-detail" type of
    interface.

    On the master (top) part of the window, is a table of the
    WorkCenters. Then when one is selected, the lower table is populated
    with an array containing the OperationTypes that the selected
    WorkCenter is able to perform.

    I have a "New" button to add a new OperationType (to the list of
    operations the WorkCenter can perform), and I now think that is where
    my problem is. I have the New button's action set to "insert:"

    After the new, blank operation type appears, I can click on it to
    bring up a popup (NSPopupButtonCell in the column) of the array of
    OperationTypes in order to select one from the list. The list is
    populated with Bindings and it all appears to work fine, but this is
    in fact where, instead of making the OperationType be one of the
    existing ones from the list, it seems to be duplicating it (as I can
    tell from it having a different pointer). The OperationType has the
    correct name, but I don't want it to be a duplicate, I want it to be
    the actual object.

    The column is bound like this:
    content = arrangedObjects.operationTypeName [OpnTypes
    (NSArrayController)]
    contentValues = arrangedObjects.operationTypeName [OpnTypes
    (NSArrayController)]
    selectedObject = arrangedObjects.operationTypeName [OpnTypes for
    Selection (NSArrayController)]

    So I guess maybe my question is: is bindings appropriate to be able
    to put exact objects from one array into another? Or will it always
    make a copy of the object that it puts into the destination array?

    > The string representation of pointers is done through a format like
    > "%x", which would suppress leading zeroes in the address. Your
    > pointers don't look wrong to me.

    thank you, that makes sense. So it is indeed the pointer to the object.
previous month october 2007 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