macOS applications are built using the Cocoa API.

Cocoa relies heavily on the late binding capabilities of Objective-C for many of its core technologies. Therefore, it's more practical to use Objective-C or Swift.

Swift has no C++ interoperability yet but Objective-C was designed to mix with C and C++. Therefore, we will use Objective-C to implement Cocoa-related functionalities.

Xcode and Clang




The noinline attribute tells the compiler to never inline a particular member function.


always inline



The always_inline attribute overrides the cost/benefit analysis and ensure the member function will be inlined.


Predefined Macros



target_link_libraries(Legend "-framework Cocoa")


To generate a signal SIGSEGV, we can invoke an assembly interruption.

__asm {int 3};

Alternatively, we can call the abort function from stdlib. http://www.cplusplus.com/reference/cstdlib/abort/

void abort(void);

Entry Point

Most macOS applications are built using Xcode and NIB files and all the initialization code for AppKit is executed behind the scene.

void NSApplicationMain(int argc, char *argv[])
    [NSApplication sharedApplication];
    [NSBundle loadNibNamed:@"main" owner:NSApp];
    [NSApp run];

We will not use NIB files and write all the initialization in Objective-C++.

It's possible to mix Objective-C++ and C++ code in the same Objective-C++ file (mm).

The entry point of the application is the main() C function.

int main(int argc, const char* argv[])


We need to handle the following initialization steps.

auto pool = [[NSAutoreleasePool alloc] init];
auto application = [NSApplication sharedApplication];

Application Delegate

Create and assign the application delegate (NSApplicationDelegate). https://developer.apple.com/documentation/appkit/nsapplicationdelegate

Some methods are implemented to respond to events, such as initialization or shutdown.

@interface ApplicationDelegate: NSObject<NSApplicationDelegate>


@implementation ApplicationDelegate

-(void)applicationWillFinishLaunching:(__unused NSNotification*)notification

-(void)applicationDidFinishLaunching:(__unused NSNotification*)notification

-(void)applicationWillTerminate:(__unused NSNotification*)notification

-(BOOL)applicationShouldTerminateAfterLastWindowClosed:(__unused NSApplication*)sender
    return YES;

-(void)handleQuit:(__unused id)sender
    [[NSApplication sharedApplication] terminate:nil];


We then create and assign the delegate to the applicati.

[application setDelegate:[[[AppDelegate alloc] init] autorelease]];


To create the main window, we need to create an instance of NSWindow. https://developer.apple.com/documentation/appkit/nswindow

auto window = [[NSWindow alloc] initWithContentRect:...];

The initWithContentRect:styleMask:backing:defer method has two important parameters. https://developer.apple.com/documentation/appkit/nswindow/1419477-initwithcontentrect

auto screenRect = [[NSScreen mainScreen] frame];
auto windowRect = NSMakeRect((screenRect.size.width - Width) * 0.5,
                             (screenRect.size.height - Height) * 0.5,
styleMask: NSWindowStyleMaskTitled |
           NSWindowStyleMaskClosable |
           NSWindowStyleMaskMiniaturizable |

Window Delegate

We define and implement a custom window delegate (NSWindowDelegate). https://developer.apple.com/documentation/appkit/nswindowdelegate

Some methods are implemented to respond to events, such as window resizing or closing.

@interface WindowDelegate: NSObject<NSWindowDelegate>


@implementation WindowDelegate

- (NSSize)windowWillResize:(NSWindow*)window
    return frameSize;

- (void)windowWillClose:(id)sender


We then create and assign the delegate to the window.

[window setDelegate:[[[WindowDelegate alloc] init] autorelease]];

Main Loop

Then, we start the main event loop of the application.

[application run];


Finally, when we leave the event loop and the applications is shutting down, we release the pool.

[pool release];