Hi Tom,

> On Sep 14, 2021, at 9:53 AM, Tom Doan via Cocoa-dev 
> <cocoa-dev@lists.apple.com> wrote:
> 
> I have a multiple platform application (Windows, Mac, GTK) that is 
> primarily organized using C++ with Objective-C used for the 
> Mac-specific interface. I recently switched to use ARC (as we are 
> using Scintilla which recently switched to ARC). However, I am 
> getting a zombied release of an NSWindow instance. So far as I 
> can tell, the memory handling of this seemed to be fine pre-ARC. 
> Unfortunately, because it's an NSWindow, the Instruments output 
> for it has 100's of toolbox calls, so it's very hard to tell where the 
> extra release is. What should I be looking for? 
> 
> Just to describe this, there's an EWindow C++ structure which has 
> the NSWindow * as a member (under Mac OS; it's an HWND under 
> Windows and Widget under GTK). It's after the delete of the 
> EWindow that things go south. I'm assuming that ARC is putting in a 
> release, but I haven't really seen any good description of how ARC 
> interacts with C++. A release there seems fine---the question is 
> where is the earlier (apparently erroneous) release.

ARC will insert code at the end of your C++ destructor to release any strong id 
members.

One possible wrinkle is the default release-when-close behavior of NSWindow.  
By default, when an NSWindow is `-close`d (which can only happen once in its 
lifetime), AppKit sends it a `-release`.  The idea is that this release 
balances the initial `+alloc`.

However, this is somewhat incompatible with ARC, which doesn’t know about this 
special behavior and will attempt to insert its own release to balance the 
alloc.

Here is an example of a program that works perfectly fine under MRR but crashes 
under ARC:

        #import <AppKit/AppKit.h>

        NSWindow *window;

        int main(void) {
                @autoreleasepool {
                        window = [[NSWindow alloc] 
initWithContentRect:NSMakeRect(0., 0., 100., 100.) 
styleMask:NSWindowStyleMaskTitled backing:NSBackingStoreBuffered defer:NO];
                        [window makeKeyAndOrderFront:nil];
                        [window close];
                        window = nil;
                }
        }

You can disable this behavior by changing the `releasedWhenClosed` property of 
the window to `NO`:

        [window setReleasedWhenClosed:NO];

Matt

_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to