Skip to content

Instantly share code, notes, and snippets.

@MasonRemaley
Last active August 23, 2019 04:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MasonRemaley/20cbb08260350517c746e84b5b707c36 to your computer and use it in GitHub Desktop.
Save MasonRemaley/20cbb08260350517c746e84b5b707c36 to your computer and use it in GitHub Desktop.
// # To test (macOS only)
// - Copy the contents of this file into a file called main.m
// - Run `clang main.m -fobjc-arc -xobjective-c++ -framework Cocoa && ./a.out`
// in bash
// - Send me:
// + The copy pasted console output from the run
// + Your macOS version (Apple > About This Mac)
// + Your clang version (`clang --version`)
// + Whether or not your computer has a Touch Bar
//
// # For The Curious
// I'm expecting the window I allocate to be subsequently be freed before exit,
// but on some computers, it is not. I suspect this is a bug in macOS as it
// seems like the extra retains are coming from AppKit & CoreFoundation, in
// something to do with the Touch Bar, but I'm not 100% positive. It's also
// possible I'm misunderstanding something fundamental about Objective-C memory
// management.
#import <Cocoa/Cocoa.h>
@interface Delegate: NSObject<NSWindowDelegate>
@end
@interface MyWindow: NSWindow
@end
int main() {
@autoreleasepool {
// Initialize the shared application
NSApplication* app = NSApplication.sharedApplication;
// Allow UI
app.activationPolicy = NSApplicationActivationPolicyRegular;
// Create the window and delegate
NSWindow *window = [[MyWindow alloc] init];
Delegate *delegate = [[Delegate alloc] init];
window.delegate = delegate;
// Have the window maintain normal refcount semantics
window.releasedWhenClosed = NO;
// Finish launching the app
[app finishLaunching];
[NSRunningApplication.currentApplication
activateWithOptions:NSApplicationActivateAllWindows];
// Show the window
[window orderFront:nil];
// Simulate the user clicking the x (canceled by the delegate). If we
// comment out this line, or don't cancel the close in the delegate, we
// don't get the leak.
[window performClose:nil];
// Actually close the window
[window close];
}
NSLog(@"exit process");
}
@implementation Delegate
- (instancetype)init {
NSLog(@"[delegate init]");
return [super init];
}
- (BOOL)windowShouldClose:(NSWindow *)sender {
NSLog(@"[delegate windowShouldClose:] (returning NO to cancel)");
return NO;
}
- (void)windowWillClose:(NSNotification *)notification {
NSLog(@"[delegate windowWillClose:]");
}
- (void)dealloc {
NSLog(@"[delegate dealloc]");
}
@end
@implementation MyWindow
- (instancetype)init {
NSLog(@"[MyWindow init]");
return [super
initWithContentRect:NSScreen.mainScreen.visibleFrame
styleMask:NSWindowStyleMaskTitled |
NSWindowStyleMaskClosable |
NSWindowStyleMaskMiniaturizable |
NSWindowStyleMaskResizable
backing:NSBackingStoreBuffered
defer:NO
];
}
- (void)dealloc {
NSLog(@"[MyWindow dealloc]");
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment