Home > Blockchain >  Crash when closing window in a MacOS application?
Crash when closing window in a MacOS application?

Time:07-02

I am attempting to create a functional MacOS application but with absolutely no xib or storyboard file just to see how it is done.

In the AppDelegate.m I create and show a window and set the application to terminate after last window closed:

#import "AppDelegate.h"
@implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)Notification {
    NSWindow *const Window = [[NSWindow alloc] initWithContentRect:(NSRect){.size = {800, 512}} styleMask:NSWindowStyleMaskTitled|NSWindowStyleMaskClosable|NSWindowStyleMaskMiniaturizable|NSWindowStyleMaskResizable backing:NSBackingStoreBuffered defer:YES];
    [Window center];
    [Window makeKeyAndOrderFront:Window];
    // Insert code here to initialize your application
}
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)Sender {
    return YES;
}
@end

AppDelegate.h:

#import <Cocoa/Cocoa.h>
@interface AppDelegate : NSObject<NSApplicationDelegate>
@end

In the Main.m file is the following:

#import <Cocoa/Cocoa.h>
#import "AppDelegate.h"
int main(void) {
    @autoreleasepool {
        [NSApplication sharedApplication].delegate = (AppDelegate *){[[AppDelegate alloc] init]}; // I also tried using setDelegate to no avail
        [NSApp run];
    }
    return 0;
}

A window is created, but the issue is that when I close the window, the app crashes, showing an Thread 1: EXC_BAD_ACCESS (code=1, address=0x20) at the [NSApp run] line in Main.m. Somehow the application does not terminate properly and crashes instead. Clearly I am missing something but the question is what?

Edit: I noticed an odd occurance which is that the crash only occurs when ARC (Automatic Reference Counting) is enabled.

CodePudding user response:

The problem is the window is automatically released (and thus deallocated) upon closure. This, combined with the automatic reference counting, presumably creates a sort of double free error. To solve this problem without disabling ARC or disabling releaseWhenClosed, Window is made a global or instance variable. Doing so will prevent ARC from releasing the window after already having been released by being closed.

NSWindow *Window;
// ...
- (void)applicationDidFinishLaunching:(NSNotification *)Notification {
    Window = [[NSWindow alloc] initWithContentRect:(NSRect){.size = {800, 512}} styleMask:NSWindowStyleMaskTitled|NSWindowStyleMaskClosable|NSWindowStyleMaskMiniaturizable|NSWindowStyleMaskResizable backing:NSBackingStoreBuffered defer:YES];
    [Window center];
    [Window makeKeyAndOrderFront:Window];
    // Insert code here to initialize your application
}
  • Related