2

Not sure why, but making a simple [[NSOpenPanel openPanel] runModal]; creates a memory leak - seen in Leaks Instrument.

Seems off.

It's an auto-released object, shouldn't it be automatically released after ARpool is drained?

Is there a way to fix this?

AWF4vk
  • 5,810
  • 3
  • 37
  • 70

4 Answers4

6

NSOpenPanel is a singleton, which means you always get the same instance of the object every time you use it. This means that the first time you call [NSOpenPanel openPanel], an instance of NSOpenPanel is created and not released.

This is not a leak, it's an optimisation. However, sometimes the Leaks instrument picks up such once-only instantiations as leaks because the instances are (by design) never released.

NSOpenPanel is such a widely-used and tested class that any leaks in its standard implementation are unlikely to exist.

Rob Keniger
  • 45,830
  • 6
  • 101
  • 134
  • Is there a way to prevent Xcode Instruments from logging singletons ? – xyz Feb 27 '12 at 20:26
  • That's not good at all :( I've notice also that in `Mac Activity Monitor` memory for my app is increase when i use `NSOpenPanel` and when i close it memory is still at the same level it doesn't decrease... – xyz Feb 28 '12 at 08:53
  • Do not use Activity Monitor for profiling. You must expect that your app will use more memory at certain points, and in the case of `NSOpenPanel` the memory increase should only occur once. Stop worrying about it. – Rob Keniger Feb 29 '12 at 07:41
  • @RobKeniger under my condition, one of my apps increase 20MB, but another one increase 40MB, do u know the reason ? – Daniel Gao Apr 16 '13 at 06:39
  • At least for Xcode 8.1 and the macOS 10.12 SDK this is not true. Every opening and closing of the NSSavePanel leaks new memory. This is not a one-time leak due to the "singleton" nature. I created singletons in my own code many times, and they never showed up as leaks in the leaks instrument. – Michael Dec 01 '16 at 09:40
3

NSOpenPanel is not a singleton. It may have been at one time but looking at the latest NSOpenPanel.h file makes it explicitly clear it is not a singleton or at the very least Apple doesn't want you taking advantage of this implementation detail.

As for the leak, I was confused on when I should release my open panel and was retaining it. From the Using the Open and Save Panels section of the File System Programming Guide your life is a lot easier in 10.7 and above:

Important: In OS X 10.6 and earlier, you must retain an open panel prior to displaying it and release it when you are done with it. Because the openPanel method returns an autoreleased object, the panel is normally released shortly after it appears on screen. Retaining the panel prevents it from being deallocated and dismissed prematurely. You do not need to retain the panel if it is attached to a window and you do not need to retain the panel in OS X 10.7 and when using ARC.

Once I stopped retaining it things got easier and became a lot easier :)

Dave Teare
  • 509
  • 3
  • 7
0

I was seeing "leaks" reported in Xcode's memory graph tool when using NSOpenPanel in an unsandboxed app built on OS X 10.11.6 using the 10.12 SDK and Swift 3.0.1. The "leaks" were reported in PlugInKit classes (PKHostPlugin, PKDiscoveryDriver, etc.) and would show up even if the only line of code was let openPanel = NSOpenPanel().

NSOpenPanel's documentation states

In a sandboxed environment, Open panels are drawn in a separate process by the powerbox, not by AppKit itself. When the user chooses a file to open, macOS adds that file to the app’s sandbox.

After I sandboxed the application, the "leaks" did not show up in Xcode's memory graph as the NSOpenPanel implementation code was no longer in the application's address space, so I no longer had to worry about it.

Andrew
  • 7,630
  • 3
  • 42
  • 51
0

Instruments is not perfect at detecting leaks - particularly for autoreleased objects, and has a tendency to have false positives. You might try creating a new NSAutoreleasePool, then draining it when you are finished with the NSOpenPanel to force release early - but I suspect you don't actually have a leak. If you are confident that the code looks good and it is autoreleased, then its probably fine.

iandotkelly
  • 9,024
  • 8
  • 48
  • 67
  • That's the only code I have. Just wondering if it's an OSX bug that should be reported. – AWF4vk Aug 08 '11 at 19:03
  • All I've read about Instruments memory leak detection is that it can result in false positives with autorelease pool. No harm in reporting it I guess, but perhaps ask a question on an Apple forum first. – iandotkelly Aug 08 '11 at 19:26