0
votes

I thought I would be clever and store the address of a C++ callback function that is strongly associated with each column in the NSTableColumn of its NSTableView. I subclassed NSTableColumn, and added a pointer as instance data. I implemented a subclassed -dealloc that destructs that pointer (and calls super dealloc, of course).

The problem is, it doesn't seem the derived NSTableColumn's -dealloc ever gets called when, for example when [myNSTableView removeTableColumn:theColumn] is called. I'm guessing its a memory management issue -- maybe the NSTableColumn is autorelease?

I couldn't find any other delegate / notification for when the NSTableColumn is removed. Must I subclass NSTableView's removeTableColumn just to intercept the column removal?

EDIT: Because some have wondered, this "pointer" is to an instance of a C++ class that was created from Boost's Signals2. It provides a signal/callback mechanism from a C++ model into an Objective-C++ method. The pointer needs to be deleted, in order to remove the callback subscription from the model's broadcasting class.

EDIT2: Regarding the definition of theColumn, it is create as below and then added to the table:

MyNSTableColumn *theColumn = [[MyNSTableColumn alloc] initWithIdentifier:columnModelAsId];

And the code in question iterates through the table's columns, removing them:

while([[compareTableView tableColumns] count] > fromWhichColumn) {
    [compareTableView removeTableColumn:[[compareTableView tableColumns] lastObject]];

There is a SEPARATE variable definition in the interface of the :

IBOutlet NSTableColumn *myDocumentColumn;

...which is pointed to my subclass (MyNSTableColumn) in IB.

(NOTE: Cell-based table -- Mac OS)

1
iOS? C++? Your tags don't seem right - JustSid
A pointer to a callback function doesn't need to be destroyed. Is it a functor (function-like object)? Also, why is important when it gets destroyed so long as it eventually does? If you suspect a leak, use the Leaks instrument to analyze which code over-retained or under-released it. - Ken Thomases
What's the declaration of theColumn? Is it a local variable or an instance variable? What's the line of code (if any) that sets it? - Peter Hosey
“a huge overlap between Cocoa and Cocoa Touch” doesn't make this an iOS question. - Peter Hosey
So, you created your column using alloc and init(WithIdentifier:). Where do you release or autorelease the column? - Peter Hosey

1 Answers

1
votes

This question was more properly answered by Peter Hosey (above), but I'll add a complete answer if others make the same mistake I did:

After creating an instance of my subclass of NSTableColumn:

MyNSTableColumn *theColumn = [[MyNSTableColumn alloc] initWithIdentifier:columnModelAsId];

...and adding it to my table:

[myTableView addTableColumn:theColumn];

I found that my subclass' dealloc method wasn't being called when removeTableColumn was being called.

The solution, as Peter pointed out above (and below), was that since I created the object, I MUST release it -- even though the NSTable took ownership/retained theColumn. So I needed to release it right after I added it:

[theColumn release];

Failing to do so was certainly a dumb mistake to make. As Ken Thomases pointed out, the Leaks instrument would've caught and diagnosed the issue in short order.