2

I'm facing a tricky issue with Cocoa's addGlobalMonitorForEventsMatchingMask leaking memory over time. In particular, with the flags provided in the example below, some events (eg. Mouse down) cause NSEvent objects to NOT being released, causing an unbounded memory growth over time.

I'm not using ARC (as this example is extracted from a native library in which Objective C is not the main language, thus I need to be able to retain control over memory allocations)

AppDelegate.m

#import "AppDelegate.h"

const unsigned long long FLAGS = NSEventMaskKeyDown | NSEventMaskKeyUp | NSEventMaskFlagsChanged | NSEventMaskLeftMouseDown | 
                                 NSEventMaskLeftMouseUp | NSEventMaskRightMouseDown | NSEventMaskRightMouseUp | 
                                 NSEventMaskOtherMouseDown | NSEventMaskOtherMouseUp;

@implementation AppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
  [NSEvent addGlobalMonitorForEventsMatchingMask:FLAGS handler:^(NSEvent *event){
    //NSLog(@"event");
  }];
}

@end

AppDelegate.h

#import <AppKit/AppKit.h>
#import <Foundation/Foundation.h>

@interface AppDelegate : NSObject <NSApplicationDelegate, NSUserNotificationCenterDelegate> {
}

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification;

@end

main.m

#include "AppDelegate.h"
#import <AppKit/AppKit.h>
#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
  @autoreleasepool {
    AppDelegate *delegate = [[AppDelegate alloc] init];

    NSApplication *application = [NSApplication sharedApplication];
    [application setDelegate:delegate];
    [application setActivationPolicy:NSApplicationActivationPolicyAccessory];
    [application run];
  }
  return 0;
}

This program is compiled with:

gcc -framework Cocoa -framework IOKit -o testleak main.m AppDelegate.m

Any idea of what could be causing it? Or what I should do to prevent it?

I've tried with multiple combinations of NSAutoreleasePools and other approaches, but none solved the issue.

My findings so far:

  • Not all events cause the leak. For example, key down events don't, while mouse events do

Screenshot of the Zombie tool displaying an increasing list of NSEvents

enter image description here

  • Maybe this helps: [Difference between Instruments (Zombies and leaks)](https://stackoverflow.com/questions/19122803/difference-between-instruments-zombies-and-leaks) and [Why am I seeing all these leaks when NSZombie is enabled?](https://stackoverflow.com/questions/10801051/why-am-i-seeing-all-these-leaks-when-nszombie-is-enabled) – Willeke Aug 14 '23 at 19:07

0 Answers0