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
}