I have an app that supports various AppleScript commands and I'm running into a memory leak issue when passing a list (array) object from a script into the app. There isn't a ton a 100% clear and helpful documentation on adding AppleScript support to your cocoa app, so I'm hoping this is just a simple oversight/error on my part and someone can help me find it.
My end goal is to have another Cocoa app compile and run the script via OSAKit but I've also tested using macOS's Script Editor.app to pass in a list and my main Cocoa app still leaks when doing it that way too:
-- This AppleScript command causes leaks
tell application "MyApp"
update database with things {"thing1", "thing2", "thing3"}
end tell
In my other Cocoa app (not the main Cocoa app), I run the above via OSAKit but it leaks there as well:
#import <OSAKit/OSAKit.h>
OSAScript *script= [[OSAScript alloc] initWithSource:[NSString stringWithFormat:@"tell application \"MyApp\"\nupdate database with things %@", listOfThings]];
NSDictionary * errorDict = nil;
NSAppleEventDescriptor *returnDescriptor = [script executeAndReturnError: &errorDict];
On the receiving end, my main Cocoa app has an NSScriptCommand class set up and can receive and respond to AppleScript commands without any other known issues. Here's what it looks like just for the list part:
MyScriptHandler.h
#import "AppDelegate.h"
#import <Cocoa/Cocoa.h>
#import <Foundation/Foundation.h>
@interface MyScriptHandler : NSScriptCommand
- (NSAppleEventDescriptor *) performDefaultImplementation;
@end
**MyScriptHandler.m**
#import "MyScriptHandler.h"
@implementation MyScriptHandler
- (NSAppleEventDescriptor *) performDefaultImplementation
{
NSString* cmdName = [[self commandDescription] commandName];
if ([cmdName isEqualToString: @"update database"])
{
// GET THE LIST AND PASS IT OFF TO APP DELEGATE FOR PROCESSING
NSMutableArray *things = [[self evaluatedArguments] valueForKey:@"things"];
[(AppDelegate *)[[NSApplication sharedApplication] delegate] updateDatabaseFromAppleScript:options];
}
return [NSAppleEventDescriptor descriptorWithBoolean:YES];
}
Not sure this is helpful, but my main Cocoa app's AppleScript dictionary (.sdef) looks like this for the command:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dictionary SYSTEM "file://localhost/System/Library/DTDs/sdef.dtd">
<dictionary title="MyApp Terminology">
<suite name="MyApp Suite" code="MyAp" description="Commands for MyApp">
<command name="update database" code="MyApUpDB" description="Update the database">
<parameter name="with things" code="optn" type="list of text" optional="yes" description="">
<cocoa key="things"/>
</parameter>
<cocoa class="MyScriptHandler"/>
</command>
</suite>
</dictionary>

type="list of text". That's not proper sdef format (and I'm surprised it worked at all). Proper format would be two key-value pairs:type="text" list="yes"I'm guessing you're memory leak happens because the app is expecting a text descriptor from the event manager (it just ignores the 'list of' part and sees 'text'), but is receiving a list descriptor. It's somehow managing the conversion, but creating the leak in the process. - Ted Wrigley