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
25b33c2afd
commit
bb229f9dc1
|
@ -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
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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];
|
||||
|
|
Loading…
Reference in New Issue