Built up a better system for handling data cleanup on Mac OS X; thanks to http://stackoverflow.com/questions/29522715/is-there-a-reliable-way-to-destroy-private-data-structures-when-a-standard-nsvie.
This commit is contained in:
parent
5a4ce7bd91
commit
93ead17eef
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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];
|
||||||
|
|
Loading…
Reference in New Issue