NSTableView copies cells - bug or feature?

  • I've been working with an NSTableView that display its rows
    using a custom subclass of NSCell that I wrote.  The cell has an
    instance variable where it holds an object that it uses for its
    drawing.  My table view's delegate sets this object through a
    setter in the tableView:willDisplayCell:... method.

    I was having troubles with this setup where my app would crash
    as soon as I selected a row.  After much banging my head against
    the wall, I discovered that one of the objects held by my cell
    was being released one too many times.  After a couple more
    hours of banging, I finally discovered that my cell (set using
    -[NSTableColumn setDataCell:]) was being copied by the table
    view to display the selected row.  Since I didn't implement
    NSCopying on my cell, it did a shallow copy of the instance
    variables, which of course leads to a release with no
    corresponding retain.

    This behavior does not seem to be documented anywhere in NSCell,
    NSTableView, or NSTableColumn.  The strangest thing is that the
    copy only happens if I select a row via a mouse click; it does
    not happen if you select rows using the arrow keys.  So, before
    I file a bug report on this, I wanted to see if anyone had
    encountered this before, or if it is actually documented
    somewhere that I missed.

    --
    Brian Webster
    <bwebster...>
    http://homepage.mac.com/bwebster
    _______________________________________________
    cocoa-dev mailing list | <cocoa-dev...>
    Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
    Do not post admin requests to the list. They will be ignored.
  • I ran into this same thing a while back and thought it was a bug too.  Then I scrutinized the documentation more closely and realized that it wasn't a behavior that was talked about very explicitly.  Since NSCell conforms to NSCopying you should be prepared to have your cell subclass copied at any time by any view (or anyone else for that matter).  In the document describing how to subclass an NSCell:

    file:///Developer/Documentation/Cocoa/TasksAndConcepts/ProgrammingTopics/ControlCell/Tasks/SubclassingNSCell.html

    It says:

    "If the subclass contains instance variables that hold pointers to objects, consider overriding copyWithZone: to duplicate the objects. The default version copies only pointers to the objects."

    If you look at the documentation for NSCopying:

    file:///System/Library/Frameworks/Foundation.framework/Resources/English.lproj/Documentation/Reference/ObjC_classic/Protocols/NSCopying.html

    You'll find the following comment:

    "Implement NSCopying by invoking the superclass's copyWithZone: when NSCopying behavior is inherited. If the superclass implementation might use the NSCopyObject function, make explicit assignments to pointer instance variables for retained objects."

    Some classes use NSCopyObject to implement the NSCopying protocol (NSCell is an example) and that NSCopyObject just copies pointer values for objects, but doesn't retain them.  Classes which inherit copying behavior from a superclass (such as a subclass of NSCell) should make sure to retain their instance variables where appropriate.

    So, it is documented in a sense, it is just rather vague about it.  If you file a bug it should probably be against the documentation rather than the code.

    Hope this helps.

    ryan

    On Thursday, June 6, 2002, at 12:06  PM, Brian Webster wrote:

    > I've been working with an NSTableView that display its rows using a custom subclass of NSCell that I wrote.  The cell has an instance variable where it holds an object that it uses for its drawing.  My table view's delegate sets this object through a setter in the tableView:willDisplayCell:... method.
    >
    > I was having troubles with this setup where my app would crash as soon as I selected a row.  After much banging my head against the wall, I discovered that one of the objects held by my cell was being released one too many times.  After a couple more hours of banging, I finally discovered that my cell (set using -[NSTableColumn setDataCell:]) was being copied by the table view to display the selected row.  Since I didn't implement NSCopying on my cell, it did a shallow copy of the instance variables, which of course leads to a release with no corresponding retain.
    >
    > This behavior does not seem to be documented anywhere in NSCell, NSTableView, or NSTableColumn.  The strangest thing is that the copy only happens if I select a row via a mouse click; it does not happen if you select rows using the arrow keys.  So, before I file a bug report on this, I wanted to see if anyone had encountered this before, or if it is actually documented somewhere that I missed.
    >
    > --
    > Brian Webster
    > <bwebster...>
    > http://homepage.mac.com/bwebster
    > _______________________________________________
    > cocoa-dev mailing list | <cocoa-dev...>
    > Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
    > Do not post admin requests to the list. They will be ignored.
    _______________________________________________
    cocoa-dev mailing list | <cocoa-dev...>
    Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
    Do not post admin requests to the list. They will be ignored.
  • OK, that documentation is pretty clear, but I still think it's
    odd that the table would only copy my cell in response to a
    mouse click and not an arrow key.  I think I'll at least file a
    bug on that, and if the copying isn't a bug, then it should
    probably be documented that NSTableColumn might make copies of
    its data cell.

    On Thursday, June 6, 2002, at 03:43  PM, Ryan Dingman wrote:

    > So, it is documented in a sense, it is just rather vague about
    > it.  If you file a bug it should probably be against the
    > documentation rather than the code.
    >
    > Hope this helps.
    >
    > ryan

    --
    Brian Webster
    <bwebster...>
    http://homepage.mac.com/bwebster
    _______________________________________________
    cocoa-dev mailing list | <cocoa-dev...>
    Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
    Do not post admin requests to the list. They will be ignored.
  • NSTableView is copying the cell in response to a mouse click and not a key press because NSTableView needs to give the cell a chance track the mouse (there is no key press tracking ;).  I'm not sure _why_ NSTableView thinks that it needs to copy the cell for mouse tracking.  I suppose that it is making some change to the cell that it doesn't want to make to the shared cell in the NSTableColumn.  But, this is why the difference exists.

    ryan

    On Thursday, June 6, 2002, at 03:02  PM, Brian Webster wrote:

    > OK, that documentation is pretty clear, but I still think it's odd that the table would only copy my cell in response to a mouse click and not an arrow key.  I think I'll at least file a bug on that, and if the copying isn't a bug, then it should probably be documented that NSTableColumn might make copies of its data cell.
    >
    > On Thursday, June 6, 2002, at 03:43  PM, Ryan Dingman wrote:
    >
    >> So, it is documented in a sense, it is just rather vague about it.  If you file a bug it should probably be against the documentation rather than the code.
    >>
    >> Hope this helps.
    >>
    >> ryan
    >
    > --
    > Brian Webster
    > <bwebster...>
    > http://homepage.mac.com/bwebster
    _______________________________________________
    cocoa-dev mailing list | <cocoa-dev...>
    Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
    Do not post admin requests to the list. They will be ignored.
previous month june 2002 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
Go to today