summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPietro Gagliardi <[email protected]>2015-04-08 15:53:50 -0400
committerPietro Gagliardi <[email protected]>2015-04-08 15:53:50 -0400
commitbb229f9dc110fbc1293be02c71ca4b37b038081e (patch)
tree2c02fee4340f9af429810c6e801df33ae249b270
parent25b33c2afd8aa772002f136c2f3bd9d56e22a0ca (diff)
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.
-rw-r--r--new/button_darwin.m9
-rw-r--r--new/container_darwin.m15
-rw-r--r--new/newcontrol_darwin.m10
-rw-r--r--new/ui_darwin.h5
-rw-r--r--new/uipriv_darwin.h10
-rw-r--r--new/window_darwin.m6
6 files changed, 34 insertions, 21 deletions
diff --git a/new/button_darwin.m b/new/button_darwin.m
index 4173f1c..fb511f7 100644
--- a/new/button_darwin.m
+++ b/new/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/new/container_darwin.m b/new/container_darwin.m
index af1acee..747ccf7 100644
--- a/new/container_darwin.m
+++ b/new/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/new/newcontrol_darwin.m b/new/newcontrol_darwin.m
index 2274190..4586331 100644
--- a/new/newcontrol_darwin.m
+++ b/new/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/new/ui_darwin.h b/new/ui_darwin.h
index e898c10..f94261a 100644
--- a/new/ui_darwin.h
+++ b/new/ui_darwin.h
@@ -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
diff --git a/new/uipriv_darwin.h b/new/uipriv_darwin.h
index effffb3..514297c 100644
--- a/new/uipriv_darwin.h
+++ b/new/uipriv_darwin.h
@@ -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
diff --git a/new/window_darwin.m b/new/window_darwin.m
index 4733530..465923c 100644
--- a/new/window_darwin.m
+++ b/new/window_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];