diff --git a/button_darwin.m b/button_darwin.m index 4173f1c8..fb511f7a 100644 --- a/button_darwin.m +++ b/button_darwin.m @@ -9,10 +9,13 @@ @implementation uiNSButton -- (void)dealloc +- (void)viewDidMoveToSuperview { - uiDarwinControlFree(self.uiC); - [super dealloc]; + if (uiDarwinControlFreeWhenAppropriate(self.uiC, [self superview])) { + [self setTarget:nil]; + self.uiC = NULL; + } + [super viewDidMoveToSuperview]; } - (IBAction)uiButtonClicked:(id)sender diff --git a/container_darwin.m b/container_darwin.m index af1acee5..747ccf7c 100644 --- a/container_darwin.m +++ b/container_darwin.m @@ -10,10 +10,17 @@ // thanks to mikeash and JtRip in irc.freenode.net/#macdev @implementation uiContainer -uiLogObjCClassAllocations( - if (self.child != NULL) - uiControlDestroy(self.child); -) +uiLogObjCClassAllocations + +- (void)viewDidMoveToSuperview +{ + if ([self superview] == nil) + if (self.child != NULL) { + uiControlDestroy(self.child); + self.child = NULL; + } + [super viewDidMoveToSuperview]; +} - (void)setFrameSize:(NSSize)s { diff --git a/newcontrol_darwin.m b/newcontrol_darwin.m index 22741908..4586331f 100644 --- a/newcontrol_darwin.m +++ b/newcontrol_darwin.m @@ -14,7 +14,7 @@ struct uiSingleViewControl { static void singleDestroy(uiControl *c) { - [S(c)->view release]; + [S(c)->view removeFromSuperview]; } static uintptr_t singleHandle(uiControl *c) @@ -90,7 +90,11 @@ uiControl *uiDarwinNewControl(Class class, BOOL inScrollView, BOOL scrollViewHas return (uiControl *) c; } -void uiDarwinControlFree(uiControl *c) +BOOL uiDarwinControlFreeWhenAppropriate(uiControl *c, NSView *newSuperview) { - uiFree(c); + if (newSuperview == nil) { + uiFree(c); + return YES; + } + return NO; } diff --git a/ui_darwin.h b/ui_darwin.h index e898c100..f94261a6 100644 --- a/ui_darwin.h +++ b/ui_darwin.h @@ -10,8 +10,9 @@ This file assumes that you have imported and "ui.h" beforehand. // uiDarwinNewControl() creates a new uiControl with the given Cocoa control inside. // The first parameter should come from [RealControlType class]. // The two scrollView parameters allow placing scrollbars on the new control. -// Your control must call uiDarwinControlFree() on the returned uiControl in its -[dealloc] method. +// Your control must call uiDarwinControlFreeWhenAppropriate() on the returned uiControl in its -[viewDidMoveToSuperview] method. +// If it returns a value other than NO, then the uiControl has been freed and you should set references to it to NULL. extern uiControl *uiDarwinNewControl(Class class, BOOL inScrollView, BOOL scrollViewHasBorder); -extern void uiDarwinControlFree(uiControl *); +extern BOOL uiDarwinControlFreeWhenAppropriate(uiControl *c, NSView *newSuperview); #endif diff --git a/uipriv_darwin.h b/uipriv_darwin.h index effffb33..514297cb 100644 --- a/uipriv_darwin.h +++ b/uipriv_darwin.h @@ -14,7 +14,7 @@ struct uiSizing { // TODO see if we can override alloc instead #ifdef uiLogAllocations #import -#define uiLogObjCClassAllocations(deallocCode) \ +#define uiLogObjCClassAllocations \ + (id)alloc \ { \ id thing; \ @@ -24,17 +24,11 @@ struct uiSizing { } \ - (void)dealloc \ { \ - deallocCode \ [super dealloc]; \ fprintf(stderr, "%p free\n", self); \ } #else -#define uiLogObjCClassAllocations(deallocCode) \ -- (void)dealloc \ -{ \ - deallocCode \ - [super dealloc]; \ -} +#define uiLogObjCClassAllocations #endif // util_darwin.m diff --git a/window_darwin.m b/window_darwin.m index 4733530f..465923cb 100644 --- a/window_darwin.m +++ b/window_darwin.m @@ -4,7 +4,9 @@ // TODO // - showing on size +// TODO clean this up @interface uiWindowDelegate : NSObject +@property (assign) NSWindow *win; @property uiWindow *w; @property int (*onClosing)(uiWindow *, void *); @property void *onClosingData; @@ -12,7 +14,7 @@ @implementation uiWindowDelegate -uiLogObjCClassAllocations() +uiLogObjCClassAllocations - (BOOL)windowShouldClose:(id)win { @@ -25,6 +27,7 @@ uiLogObjCClassAllocations() // after this method returns we assume the window will be released (see below), so we can go too - (void)windowWillClose:(NSNotification *)note { + [self.win setDelegate:nil]; // see http://stackoverflow.com/a/29523141/3408572 uiFree(self.w); [self release]; } @@ -63,6 +66,7 @@ uiWindow *uiNewWindow(char *title, int width, int height) [w->w setContentView:((NSView *) w->container)]; w->d = [uiWindowDelegate new]; + w->d.win = w->w; w->d.w = w; w->d.onClosing = defaultOnClosing; [w->w setDelegate:w->d];