I'm using the following simple Objective-C program to receive messages from another process and display alerts, using an NSPasteboard as the means of communication between the 2 processes. The program works for me, but I've observed that the program is consuming huge amounts of RAM, regardless of whether the partner process is posting new messages to the pasteboard and the inner alert block is entered. It produces 1G swapfiles in /private/var/vm/
every few minutes while it runs until I kill it.
I ran the program through Xcode Instruments, and I am seeing that [NSPasteboard canReadObjectForClasses:options:]
is creating persistent __NSArrayI
objects every time it is called, which is the source of the RAM bloat. Can anyone else confirm this? Is this a bug in [NSPasteboard canReadObjectForClasses:options:]
, or should I just be performing this task differently?
EDIT:
I originally forgot to enable ARC. Even with ARC enabled however, memory usage growth still greatly outpaces automatic memory release, and the swapfiles are still being created over time. Does anyone have suggestions on how I can rewrite this script to use a better convention than while(true)
so that [NSPasteboard canReadObjectForClasses:options:]
is called less? It also still strikes me as odd that this AppKit function isn't automatically releasing the __NSArrayI
objects it creates and assumes ARC will take care of it; is this common practice for such a library?
#import <Foundation/Foundation.h>
#import <CoreFoundation/CoreFoundation.h>
#import <AppKit/Appkit.h>
int main(void) {
NSPasteboard *pb = [NSPasteboard pasteboardWithName:@"alertBoard"];
NSArray *clsss = @[[NSString class]];
while(true) {
if ([pb canReadObjectForClasses:clsss options:nil]) {
NSArray *contents = [pb readObjectsForClasses:@[[NSString class]] options: nil];
CFStringRef msg = (__bridge CFStringRef) [contents firstObject];
[pb clearContents];
CFUserNotificationDisplayNotice(2, 3, NULL, NULL, NULL, CFSTR("Alert"), msg, NULL);
}
}
return 0;
}
I'm compiling the program like so g++ -framework Foundation -framework CoreFoundation -framework AppKit -fobjc-arc alertDaemon.m -o alertDaemon
. The problem occurs regardless of the other process, so running the program for a few minutes is all that's needed to observe swapfile creation.