This commit is contained in:
Pietro Gagliardi 2015-04-08 15:53:50 -04:00
parent 5a4ce7bd91
commit 93ead17eef
6 changed files with 34 additions and 21 deletions

View File

@ -9,10 +9,13 @@
@implementation uiNSButton @implementation uiNSButton
- (void)dealloc - (void)viewDidMoveToSuperview
{ {
uiDarwinControlFree(self.uiC); if (uiDarwinControlFreeWhenAppropriate(self.uiC, [self superview])) {
[super dealloc]; [self setTarget:nil];
self.uiC = NULL;
}
[super viewDidMoveToSuperview];
} }
- (IBAction)uiButtonClicked:(id)sender - (IBAction)uiButtonClicked:(id)sender

View File

@ -10,10 +10,17 @@
// thanks to mikeash and JtRip in irc.freenode.net/#macdev // thanks to mikeash and JtRip in irc.freenode.net/#macdev
@implementation uiContainer @implementation uiContainer
uiLogObjCClassAllocations( uiLogObjCClassAllocations
if (self.child != NULL)
uiControlDestroy(self.child); - (void)viewDidMoveToSuperview
) {
if ([self superview] == nil)
if (self.child != NULL) {
uiControlDestroy(self.child);
self.child = NULL;
}
[super viewDidMoveToSuperview];
}
- (void)setFrameSize:(NSSize)s - (void)setFrameSize:(NSSize)s
{ {

View File

@ -14,7 +14,7 @@ struct uiSingleViewControl {
static void singleDestroy(uiControl *c) static void singleDestroy(uiControl *c)
{ {
[S(c)->view release]; [S(c)->view removeFromSuperview];
} }
static uintptr_t singleHandle(uiControl *c) static uintptr_t singleHandle(uiControl *c)
@ -90,7 +90,11 @@ uiControl *uiDarwinNewControl(Class class, BOOL inScrollView, BOOL scrollViewHas
return (uiControl *) c; return (uiControl *) c;
} }
void uiDarwinControlFree(uiControl *c) BOOL uiDarwinControlFreeWhenAppropriate(uiControl *c, NSView *newSuperview)
{ {
uiFree(c); if (newSuperview == nil) {
uiFree(c);
return YES;
}
return NO;
} }

View File

@ -10,8 +10,9 @@ This file assumes that you have imported <Cocoa/Cocoa.h> and "ui.h" beforehand.
// uiDarwinNewControl() creates a new uiControl with the given Cocoa control inside. // uiDarwinNewControl() creates a new uiControl with the given Cocoa control inside.
// The first parameter should come from [RealControlType class]. // The first parameter should come from [RealControlType class].
// The two scrollView parameters allow placing scrollbars on the new control. // 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 uiControl *uiDarwinNewControl(Class class, BOOL inScrollView, BOOL scrollViewHasBorder);
extern void uiDarwinControlFree(uiControl *); extern BOOL uiDarwinControlFreeWhenAppropriate(uiControl *c, NSView *newSuperview);
#endif #endif

View File

@ -14,7 +14,7 @@ struct uiSizing {
// TODO see if we can override alloc instead // TODO see if we can override alloc instead
#ifdef uiLogAllocations #ifdef uiLogAllocations
#import <stdio.h> #import <stdio.h>
#define uiLogObjCClassAllocations(deallocCode) \ #define uiLogObjCClassAllocations \
+ (id)alloc \ + (id)alloc \
{ \ { \
id thing; \ id thing; \
@ -24,17 +24,11 @@ struct uiSizing {
} \ } \
- (void)dealloc \ - (void)dealloc \
{ \ { \
deallocCode \
[super dealloc]; \ [super dealloc]; \
fprintf(stderr, "%p free\n", self); \ fprintf(stderr, "%p free\n", self); \
} }
#else #else
#define uiLogObjCClassAllocations(deallocCode) \ #define uiLogObjCClassAllocations
- (void)dealloc \
{ \
deallocCode \
[super dealloc]; \
}
#endif #endif
// util_darwin.m // util_darwin.m

View File

@ -4,7 +4,9 @@
// TODO // TODO
// - showing on size // - showing on size
// TODO clean this up
@interface uiWindowDelegate : NSObject <NSWindowDelegate> @interface uiWindowDelegate : NSObject <NSWindowDelegate>
@property (assign) NSWindow *win;
@property uiWindow *w; @property uiWindow *w;
@property int (*onClosing)(uiWindow *, void *); @property int (*onClosing)(uiWindow *, void *);
@property void *onClosingData; @property void *onClosingData;
@ -12,7 +14,7 @@
@implementation uiWindowDelegate @implementation uiWindowDelegate
uiLogObjCClassAllocations() uiLogObjCClassAllocations
- (BOOL)windowShouldClose:(id)win - (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 // after this method returns we assume the window will be released (see below), so we can go too
- (void)windowWillClose:(NSNotification *)note - (void)windowWillClose:(NSNotification *)note
{ {
[self.win setDelegate:nil]; // see http://stackoverflow.com/a/29523141/3408572
uiFree(self.w); uiFree(self.w);
[self release]; [self release];
} }
@ -63,6 +66,7 @@ uiWindow *uiNewWindow(char *title, int width, int height)
[w->w setContentView:((NSView *) w->container)]; [w->w setContentView:((NSView *) w->container)];
w->d = [uiWindowDelegate new]; w->d = [uiWindowDelegate new];
w->d.win = w->w;
w->d.w = w; w->d.w = w;
w->d.onClosing = defaultOnClosing; w->d.onClosing = defaultOnClosing;
[w->w setDelegate:w->d]; [w->w setDelegate:w->d];