This commit is contained in:
Pietro Gagliardi 2015-04-08 15:53:50 -04:00
parent 25b33c2afd
commit bb229f9dc1
6 changed files with 34 additions and 21 deletions

View File

@ -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

View File

@ -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
{

View File

@ -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;
}

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.
// 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

View File

@ -14,7 +14,7 @@ struct uiSizing {
// TODO see if we can override alloc instead
#ifdef uiLogAllocations
#import <stdio.h>
#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

View File

@ -4,7 +4,9 @@
// TODO
// - showing on size
// TODO clean this up
@interface uiWindowDelegate : NSObject <NSWindowDelegate>
@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];