From b46ab89ec227e9f7d026a4f60db0ffc632791a03 Mon Sep 17 00:00:00 2001 From: Greg Lucas Date: Mon, 16 May 2022 21:06:03 -0600 Subject: [PATCH 1/2] MNT: Change objective C code to Automatic Reference Counting (ARC) This updates the objective C macosx backend to use automatic reference counting instead of relying on manual tracking and releasing of the memory. --- setupext.py | 2 +- src/_macosx.m | 61 +++++++++++---------------------------------------- 2 files changed, 14 insertions(+), 49 deletions(-) diff --git a/setupext.py b/setupext.py index eaa66bdfa708..0ab67839dcf1 100644 --- a/setupext.py +++ b/setupext.py @@ -762,7 +762,7 @@ def get_extensions(self): 'matplotlib.backends._macosx', [ 'src/_macosx.m' ]) - ext.extra_compile_args.extend(['-Werror']) + ext.extra_compile_args.extend(['-Werror', '-fobjc-arc']) ext.extra_link_args.extend(['-framework', 'Cocoa']) if platform.python_implementation().lower() == 'pypy': ext.extra_compile_args.append('-DPYPY=1') diff --git a/src/_macosx.m b/src/_macosx.m index e6ac546a2d34..1869a22bb8fc 100755 --- a/src/_macosx.m +++ b/src/_macosx.m @@ -1,3 +1,7 @@ +#if ! __has_feature(objc_arc) +#error This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC). +#endif + #define PY_SSIZE_T_CLEAN #include #include @@ -333,7 +337,6 @@ static CGFloat _get_device_scale(CGContextRef cr) FigureCanvas_dealloc(FigureCanvas* self) { [self->view setCanvas: NULL]; - [self->view release]; Py_TYPE(self)->tp_free((PyObject*)self); } @@ -341,7 +344,7 @@ static CGFloat _get_device_scale(CGContextRef cr) FigureCanvas_repr(FigureCanvas* self) { return PyUnicode_FromFormat("FigureCanvas object %p wrapping NSView %p", - (void*)self, (void*)(self->view)); + (void*)self, (__bridge void*)(self->view)); } static PyObject* @@ -545,7 +548,6 @@ static CGFloat _get_device_scale(CGContextRef cr) if (!window) { return NULL; } FigureManager *self = (FigureManager*)type->tp_alloc(type, 0); if (!self) { - [window release]; return NULL; } self->window = window; @@ -598,7 +600,7 @@ static CGFloat _get_device_scale(CGContextRef cr) FigureManager_repr(FigureManager* self) { return PyUnicode_FromFormat("FigureManager object %p wrapping NSWindow %p", - (void*) self, (void*)(self->window)); + (void*) self, (__bridge void*)(self->window)); } static void @@ -648,7 +650,7 @@ static CGFloat _get_device_scale(CGContextRef cr) PyErr_SetString(PyExc_RuntimeError, "Could not convert to NSString*"); return NULL; } - NSImage* image = [[[NSImage alloc] initByReferencingFile: ns_icon_path] autorelease]; + NSImage* image = [[NSImage alloc] initByReferencingFile: ns_icon_path]; if (!image) { PyErr_SetString(PyExc_RuntimeError, "Could not create NSImage*"); return NULL; @@ -677,9 +679,9 @@ static CGFloat _get_device_scale(CGContextRef cr) if (!PyArg_ParseTuple(args, "s", &title)) { return NULL; } - NSString* ns_title = [[[NSString alloc] - initWithCString: title - encoding: NSUTF8StringEncoding] autorelease]; + NSString* ns_title = [[NSString alloc] + initWithCString: title + encoding: NSUTF8StringEncoding]; [self->window setTitle: ns_title]; Py_RETURN_NONE; } @@ -766,7 +768,7 @@ @interface NavigationToolbar2Handler : NSObject NSButton* zoombutton; } - (NavigationToolbar2Handler*)initWithToolbar:(PyObject*)toolbar; -- (void)installCallbacks:(SEL[7])actions forButtons:(NSButton*[7])buttons; +- (void)installCallbacks:(SEL[7])actions forButtons:(NSButton*__strong [7])buttons; - (void)home:(id)sender; - (void)back:(id)sender; - (void)forward:(id)sender; @@ -787,12 +789,12 @@ - (void)save_figure:(id)sender; @implementation NavigationToolbar2Handler - (NavigationToolbar2Handler*)initWithToolbar:(PyObject*)theToolbar { - [self init]; + self = [self init]; toolbar = theToolbar; return self; } -- (void)installCallbacks:(SEL[7])actions forButtons:(NSButton*[7])buttons +- (void)installCallbacks:(SEL[7])actions forButtons:(NSButton*__strong [7])buttons { int i; for (i = 0; i < 7; i++) { @@ -833,7 +835,6 @@ -(void)save_figure:(id)sender { gil_call_method(toolbar, "save_figure"); } if (!handler) { return NULL; } NavigationToolbar2 *self = (NavigationToolbar2*)type->tp_alloc(type, 0); if (!self) { - [handler release]; return NULL; } self->handler = handler; @@ -925,8 +926,6 @@ -(void)save_figure:(id)sender { gil_call_method(toolbar, "save_figure"); } [buttons[i] setImagePosition: NSImageOnly]; [buttons[i] setToolTip: tooltip]; [[window contentView] addSubview: buttons[i]]; - [buttons[i] release]; - [image release]; rect.origin.x += rect.size.width + gap; } @@ -949,7 +948,6 @@ -(void)save_figure:(id)sender { gil_call_method(toolbar, "save_figure"); } /* if selectable, the messagebox can become first responder, * which is not supposed to happen */ [[window contentView] addSubview: messagebox]; - [messagebox release]; [[window contentView] display]; self->messagebox = messagebox; @@ -959,7 +957,6 @@ -(void)save_figure:(id)sender { gil_call_method(toolbar, "save_figure"); } static void NavigationToolbar2_dealloc(NavigationToolbar2 *self) { - [self->handler release]; Py_TYPE(self)->tp_free((PyObject*)self); } @@ -1060,36 +1057,6 @@ + (WindowServerConnectionManager *)sharedManager return sharedWindowServerConnectionManager; } -+ (id)allocWithZone:(NSZone *)zone -{ - return [[self sharedManager] retain]; -} - -+ (id)copyWithZone:(NSZone *)zone -{ - return self; -} - -+ (id)retain -{ - return self; -} - -- (NSUInteger)retainCount -{ - return NSUIntegerMax; //denotes an object that cannot be released -} - -- (oneway void)release -{ - // Don't release a singleton object -} - -- (id)autorelease -{ - return self; -} - - (void)launch:(NSNotification*)notification { CFRunLoopRef runloop; @@ -1167,7 +1134,6 @@ - (void)dealloc * content view of this window was increased during the call to addSubview, * and is decreased during the call to [super dealloc]. */ - [super dealloc]; } @end @@ -1189,7 +1155,6 @@ - (void)dealloc { FigureCanvas* fc = (FigureCanvas*)canvas; if (fc) { fc->view = NULL; } - [super dealloc]; } - (void)setCanvas: (PyObject*)newCanvas From ec0a325ab08f3bffe2c60bde6cacc83c501e57ee Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Fri, 24 Jun 2022 20:08:34 -0400 Subject: [PATCH 2/2] FIX: remove one more autorelease --- src/_macosx.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/_macosx.m b/src/_macosx.m index 1869a22bb8fc..796508bc2f6a 100755 --- a/src/_macosx.m +++ b/src/_macosx.m @@ -938,7 +938,7 @@ -(void)save_figure:(id)sender { gil_call_method(toolbar, "save_figure"); } // Make it a zero-width box if we don't have enough room rect.size.width = fmax(bounds.size.width - rect.origin.x, 0); rect.origin.x = bounds.size.width - rect.size.width; - NSTextView* messagebox = [[[NSTextView alloc] initWithFrame: rect] autorelease]; + NSTextView* messagebox = [[NSTextView alloc] initWithFrame: rect]; messagebox.textContainer.maximumNumberOfLines = 2; messagebox.textContainer.lineBreakMode = NSLineBreakByTruncatingTail; messagebox.alignment = NSTextAlignmentRight;