[vtkusers] vtkCocoaRenderWindow bug?
Antoine Rosset
rossetantoine at bluewin.ch
Sat Apr 5 01:32:00 EDT 2008
Ok, thanks. You are right.
Yes, I'm having problems with this cocoamanager variable and memory
management:
To create your own NSWindow, you create a subclass of vtkCocoaGLView
and you initialize it with:
-(id)initWithFrame:(NSRect)frame {
if ( self = [super initWithFrame:frame])
{
_renderer = vtkRenderer::New();
_cocoaRenderWindow = vtkCocoaRenderWindow::New();
_cocoaRenderWindow->SetWindowId( [self window]);
_cocoaRenderWindow->SetDisplayId( self);
_cocoaRenderWindow->AddRenderer(_renderer);
_interactor = vtkCocoaRenderWindowInteractor::New();
_interactor->SetRenderWindow(_cocoaRenderWindow);
and a destructor
-(void)dealloc
{
_renderer->Delete();
_cocoaRenderWindow->Delete();
_interactor->Delete();
[super dealloc];
}
By calling _cocoaRenderWindow->SetDisplayId( self);, you increase the
retain count of the NSView, because you add it to the cocoamanager
NSDictionary
Hence, the NSView will not be released automatically, because you will
remove this NSView from the cocoamanager in the destructor of
vtkCocoaRenderWindow AND the destructor of vtkCocoaRenderWindow will
be called from the dealloc of the NSView, that cannot be called
because the cocoamanager retains the NSView. (I hope it's not too
confuse... :-))
To avoid this memory leak, I had to create a 'prepareForRelease'
function, that I call from my NSWindowController dealloc : [myVTKView
prepareForRelease]
- (void) prepareForRelease
{
_cocoaRenderWindow->SetWindowId( 0L);
_cocoaRenderWindow->SetDisplayId( 0L);
}
Then, the NSView will be released.
To identify the problem, put an NSLog in your dealloc of your VTKView
subclass, to see if it is called.
The solution would be to put the 'displayId' in a variable, instead of
adding it to the NSDictionary.
What do you think? Is there another way of subclassing the VTKView ?
On 5 avr. 08, at 01:35, Sean McBride wrote:
> On 4/4/08 11:49 PM, Antoine Rosset said:
>
>> In 'vtkCocoaRenderWindow::vtkCocoaRenderWindow()' you create a
>> CocoaManager variable with a NSMutableDictionary. This variable is
>> created as an autorelease object : that means that this object is not
>> retained and can be released by the OS when it quits the function
>> (during the next runloop).
>>
>> In my opinion, it should be
>>
>> this->SetCocoaManager(reinterpret_cast<void *>( [[NSMutableDictionary
>> dictionary] retain]));
>> instead of
>> this->SetCocoaManager(reinterpret_cast<void *>( [NSMutableDictionary
>> dictionary]));
>>
>> and then in the destructor
>>
>> // Release the cocoa object manager.
>> NSMutableDictionary* manager = reinterpret_cast<NSMutableDictionary
>> *>(this->GetCocoaManager());
>> [manager release];
>> this->SetCocoaManager(NULL);
>>
>> What do you think?
>
> Look at the implementation of SetCocoaManager() itself, it does the
> retain and release. Is this code giving you problems? Or did it just
> look weird on inspection?
>
> --
> ____________________________________________________________
> Sean McBride, B. Eng sean at rogue-research.com
> Rogue Research www.rogue-research.com
> Mac Software Developer Montréal, Québec, Canada
>
More information about the vtkusers
mailing list