Fix crash when closing program on OS X

This fixes #14. Autorelease pools need to be used to make sure objects get properly released. Unfortunately this produces a new error when menuManager gets deallocated, which I am looking at fixing:

map.m:25:mapDestroy() POSSIBLE IMPLEMENTATION BUG; CONTACT ANDLABS:
attempt to destroy map with items inside
This commit is contained in:
Kevin Wojniak 2016-05-23 21:09:46 -07:00
parent 156c3584f7
commit 2ebb9052cc
2 changed files with 36 additions and 14 deletions

View File

@ -2,6 +2,7 @@
#import "uipriv_darwin.h" #import "uipriv_darwin.h"
static BOOL canQuit = NO; static BOOL canQuit = NO;
static NSAutoreleasePool *globalPool;
@implementation applicationClass @implementation applicationClass
@ -72,7 +73,8 @@ static BOOL canQuit = NO;
- (void)dealloc - (void)dealloc
{ {
[self.menuManager release]; // Apple docs: "Don't Use Accessor Methods in Initializer Methods and dealloc"
[_menuManager release];
[super dealloc]; [super dealloc];
} }
@ -99,6 +101,10 @@ uiInitOptions options;
const char *uiInit(uiInitOptions *o) const char *uiInit(uiInitOptions *o)
{ {
globalPool = [[NSAutoreleasePool alloc] init];
@autoreleasepool {
options = *o; options = *o;
[applicationClass sharedApplication]; [applicationClass sharedApplication];
// don't check for a NO return; something (launch services?) causes running from application bundles to always return NO when asking to change activation policy, even if the change is to the same activation policy! // don't check for a NO return; something (launch services?) causes running from application bundles to always return NO when asking to change activation policy, even if the change is to the same activation policy!
@ -109,21 +115,29 @@ const char *uiInit(uiInitOptions *o)
initAlloc(); initAlloc();
// always do this so we always have an application menu // always do this so we always have an application menu
appDelegate().menuManager = [menuManager new]; appDelegate().menuManager = [[menuManager new] autorelease];
[realNSApp() setMainMenu:[appDelegate().menuManager makeMenubar]]; [realNSApp() setMainMenu:[appDelegate().menuManager makeMenubar]];
setupFontPanel(); setupFontPanel();
return NULL; return NULL;
} // @autoreleasepool
} }
void uiUninit(void) void uiUninit(void)
{ {
@autoreleasepool {
uninitMenus(); uninitMenus();
[realNSApp() setDelegate:nil];
[appDelegate() release]; [appDelegate() release];
[realNSApp() setDelegate:nil];
[realNSApp() release]; [realNSApp() release];
uninitAlloc(); uninitAlloc();
} // @autoreleasepool
[globalPool release];
} }
void uiFreeInitError(const char *err) void uiFreeInitError(const char *err)

View File

@ -116,14 +116,14 @@ enum {
NSMenu *servicesMenu; NSMenu *servicesMenu;
appName = [[NSProcessInfo processInfo] processName]; appName = [[NSProcessInfo processInfo] processName];
appMenuItem = [[NSMenuItem alloc] initWithTitle:appName action:NULL keyEquivalent:@""]; appMenuItem = [[[NSMenuItem alloc] initWithTitle:appName action:NULL keyEquivalent:@""] autorelease];
appMenu = [[NSMenu alloc] initWithTitle:appName]; appMenu = [[[NSMenu alloc] initWithTitle:appName] autorelease];
[appMenuItem setSubmenu:appMenu]; [appMenuItem setSubmenu:appMenu];
[menubar addItem:appMenuItem]; [menubar addItem:appMenuItem];
// first is About // first is About
title = [@"About " stringByAppendingString:appName]; title = [@"About " stringByAppendingString:appName];
item = [[NSMenuItem alloc] initWithTitle:title action:@selector(onClicked:) keyEquivalent:@""]; item = [[[NSMenuItem alloc] initWithTitle:title action:@selector(onClicked:) keyEquivalent:@""] autorelease];
[item setTarget:self]; [item setTarget:self];
[appMenu addItem:item]; [appMenu addItem:item];
self.aboutItem = item; self.aboutItem = item;
@ -131,7 +131,7 @@ enum {
[appMenu addItem:[NSMenuItem separatorItem]]; [appMenu addItem:[NSMenuItem separatorItem]];
// next is Preferences // next is Preferences
item = [[NSMenuItem alloc] initWithTitle:@"Preferences…" action:@selector(onClicked:) keyEquivalent:@","]; item = [[[NSMenuItem alloc] initWithTitle:@"Preferences…" action:@selector(onClicked:) keyEquivalent:@","] autorelease];
[item setTarget:self]; [item setTarget:self];
[appMenu addItem:item]; [appMenu addItem:item];
self.preferencesItem = item; self.preferencesItem = item;
@ -139,8 +139,8 @@ enum {
[appMenu addItem:[NSMenuItem separatorItem]]; [appMenu addItem:[NSMenuItem separatorItem]];
// next is Services // next is Services
item = [[NSMenuItem alloc] initWithTitle:@"Services" action:NULL keyEquivalent:@""]; item = [[[NSMenuItem alloc] initWithTitle:@"Services" action:NULL keyEquivalent:@""] autorelease];
servicesMenu = [[NSMenu alloc] initWithTitle:@"Services"]; servicesMenu = [[[NSMenu alloc] initWithTitle:@"Services"] autorelease];
[item setSubmenu:servicesMenu]; [item setSubmenu:servicesMenu];
[realNSApp() setServicesMenu:servicesMenu]; [realNSApp() setServicesMenu:servicesMenu];
[appMenu addItem:item]; [appMenu addItem:item];
@ -149,14 +149,14 @@ enum {
// next are the three hiding options // next are the three hiding options
title = [@"Hide " stringByAppendingString:appName]; title = [@"Hide " stringByAppendingString:appName];
item = [[NSMenuItem alloc] initWithTitle:title action:@selector(hide:) keyEquivalent:@"h"]; item = [[[NSMenuItem alloc] initWithTitle:title action:@selector(hide:) keyEquivalent:@"h"] autorelease];
// the .xib file says they go to -1 ("First Responder", which sounds wrong...) // the .xib file says they go to -1 ("First Responder", which sounds wrong...)
// to do that, we simply leave the target as nil // to do that, we simply leave the target as nil
[appMenu addItem:item]; [appMenu addItem:item];
item = [[NSMenuItem alloc] initWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"]; item = [[[NSMenuItem alloc] initWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"] autorelease];
[item setKeyEquivalentModifierMask:(NSAlternateKeyMask | NSCommandKeyMask)]; [item setKeyEquivalentModifierMask:(NSAlternateKeyMask | NSCommandKeyMask)];
[appMenu addItem:item]; [appMenu addItem:item];
item = [[NSMenuItem alloc] initWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""]; item = [[[NSMenuItem alloc] initWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""] autorelease];
[appMenu addItem:item]; [appMenu addItem:item];
[appMenu addItem:[NSMenuItem separatorItem]]; [appMenu addItem:[NSMenuItem separatorItem]];
@ -164,7 +164,7 @@ enum {
// and finally Quit // and finally Quit
// DON'T use @selector(terminate:) as the action; we handle termination ourselves // DON'T use @selector(terminate:) as the action; we handle termination ourselves
title = [@"Quit " stringByAppendingString:appName]; title = [@"Quit " stringByAppendingString:appName];
item = [[NSMenuItem alloc] initWithTitle:title action:@selector(onQuitClicked:) keyEquivalent:@"q"]; item = [[[NSMenuItem alloc] initWithTitle:title action:@selector(onQuitClicked:) keyEquivalent:@"q"] autorelease];
[item setTarget:self]; [item setTarget:self];
[appMenu addItem:item]; [appMenu addItem:item];
self.quitItem = item; self.quitItem = item;
@ -174,7 +174,7 @@ enum {
{ {
NSMenu *menubar; NSMenu *menubar;
menubar = [[NSMenu alloc] initWithTitle:@""]; menubar = [[[NSMenu alloc] initWithTitle:@""] autorelease];
[self buildApplicationMenu:menubar]; [self buildApplicationMenu:menubar];
return menubar; return menubar;
} }
@ -222,6 +222,8 @@ void uiMenuItemSetChecked(uiMenuItem *item, int checked)
static uiMenuItem *newItem(uiMenu *m, int type, const char *name) static uiMenuItem *newItem(uiMenu *m, int type, const char *name)
{ {
@autoreleasepool {
uiMenuItem *item; uiMenuItem *item;
if (menusFinalized) if (menusFinalized)
@ -257,6 +259,8 @@ static uiMenuItem *newItem(uiMenu *m, int type, const char *name)
[m->items addObject:[NSValue valueWithPointer:item]]; [m->items addObject:[NSValue valueWithPointer:item]];
return item; return item;
} // @autoreleasepool
} }
uiMenuItem *uiMenuAppendItem(uiMenu *m, const char *name) uiMenuItem *uiMenuAppendItem(uiMenu *m, const char *name)
@ -294,6 +298,8 @@ void uiMenuAppendSeparator(uiMenu *m)
uiMenu *uiNewMenu(const char *name) uiMenu *uiNewMenu(const char *name)
{ {
@autoreleasepool {
uiMenu *m; uiMenu *m;
if (menusFinalized) if (menusFinalized)
@ -316,6 +322,8 @@ uiMenu *uiNewMenu(const char *name)
[menus addObject:[NSValue valueWithPointer:m]]; [menus addObject:[NSValue valueWithPointer:m]];
return m; return m;
} // @autoreleasepool
} }
void finalizeMenus(void) void finalizeMenus(void)