View Issue Details

IDProjectCategoryView StatusLast Update
0035944LazarusWidgetsetpublic2019-08-12 18:08
ReporterZoë PetersonAssigned ToDmitry Boyarintsev 
PrioritynormalSeverityminorReproducibilityalways
Status resolvedResolutionfixed 
Product Version2.0.3 (SVN)Product Build 
Target VersionFixed in Version 
Summary0035944: NSView resource leak when using TCustomControl
DescriptionControls embedded in a TCocoaManualScrollView (TCustomControl) currently leak their NSView handles.

EmbedInManualScrollView is used in two places, TCocoaWSCustomControl.CreateHandle and TCocoaWSCustomSplitter.CreateHandle. Both allocate the base control, call EmbedInManualScrollView, and return the scroll view as the result. At that point, the inner view has a retainCount of 2, one from the alloc.init and one from the scrollview's subview reference. Neither TCocoaWSCustomControl nor TCocoaWSCustomSplitter have DestroyHandle implementations, so the default one runs, which only releases the "Handle" property. The manual scroll view is released and deallocated, but the embedded one still has the outstanding reference. You can verify that by adding logging to the places where TCocoaCustomControl are allocated and in its dealloc; there will be many more alloc calls than dealloc ones.

EmbedInScrollView has an optional parameter (defaults to true) that releases the embedded view after the scroll view is created and the subview is assigned. That keeps the resulting retain count at 1.

This patch adds the same release behavior to EmbedInManualScrollView, though since there isn't anywhere that doesn't want that behavior, I left out making it optional.

As an alternative, TCocoaManaualScrollView could call the release when it's deallocated, or the relevant controls could do it in DestroyHandle. TCocoaSpinEdit does similar embedding and manages the reference counts explicitly in lclReleaseSubcontrols.
TagsNo tags attached.
Fixed in Revision61688
LazTarget-
WidgetsetCocoa
Attached Files
  • ManualScrollView_leak.patch (322 bytes)
    --- a/lcl/interfaces/cocoa/cocoawscommon.pas
    +++ b/lcl/interfaces/cocoa/cocoawscommon.pas
    @@ -269,6 +269,7 @@ begin
       {$else}
       AView.setHidden(false);
       {$endif}
    +  AView.release;
       SetViewDefaults(Result);
       if AView.isKindOfClass(TCocoaCustomControl) then
         TCocoaCustomControl(AView).auxMouseByParent := true;
    

Activities

Zoë Peterson

2019-08-10 00:34

reporter  

ManualScrollView_leak.patch (322 bytes)
--- a/lcl/interfaces/cocoa/cocoawscommon.pas
+++ b/lcl/interfaces/cocoa/cocoawscommon.pas
@@ -269,6 +269,7 @@ begin
   {$else}
   AView.setHidden(false);
   {$endif}
+  AView.release;
   SetViewDefaults(Result);
   if AView.isKindOfClass(TCocoaCustomControl) then
     TCocoaCustomControl(AView).auxMouseByParent := true;

Dmitry Boyarintsev

2019-08-12 18:08

developer   ~0117658

thanks for the patch, applied!
please test and close if ok

Issue History

Date Modified Username Field Change
2019-08-10 00:34 Zoë Peterson New Issue
2019-08-10 00:34 Zoë Peterson File Added: ManualScrollView_leak.patch
2019-08-12 18:06 Dmitry Boyarintsev Assigned To => Dmitry Boyarintsev
2019-08-12 18:06 Dmitry Boyarintsev Status new => assigned
2019-08-12 18:08 Dmitry Boyarintsev Status assigned => resolved
2019-08-12 18:08 Dmitry Boyarintsev Resolution open => fixed
2019-08-12 18:08 Dmitry Boyarintsev Fixed in Revision => 61688
2019-08-12 18:08 Dmitry Boyarintsev LazTarget => -
2019-08-12 18:08 Dmitry Boyarintsev Widgetset Cocoa => Cocoa
2019-08-12 18:08 Dmitry Boyarintsev Note Added: 0117658