I do memory inspection by Activity monitor.app
Post
Replies
Boosts
Views
Activity
I test NSAppleScript to move desktop windows, src as below.
And memory increase faster when moving windows.
When stop moving window, memory usage increase as well.
It seems memory not be released somehow.
NSString *command = [NSString stringWithFormat:
//@"#!/bin/bash\nosascript <<EOF\n"
@"try\n"
@"tell application "System Events"\n"
@"tell process "%@"\n"
@"tell window %d\n"
@"set {position, size} to {{%d,%d},{%d,%d}}\n"
@"end tell\n"
@"end tell\n"
@"end tell\n"
@"on error errMsg number errorNumber\n"
@"return "Error with number: " & errorNumber as text\n"
@"end try", ownerName, winIdx, (int)rect.origin.x, (int)rect.origin.y, (int)rect.size.width, (int)rect.size.height];
NSDictionary* errorDict;
NSAppleEventDescriptor* returnDescriptor = NULL;
NSAppleScript* scriptObject = [[NSAppleScript alloc] initWithSource:command];
returnDescriptor = [scriptObject executeAndReturnError: &errorDict];
The first time you fire up NSAppleScript that’ll allocate a whole bunch of memory for that subsystem.
-> Is there a way to avoid allocating a bunch of memory? How to release memory when end of NSAppleScript command?
I try not to do next if scriptObject nil (src as below)
" NSAppleScript* scriptObject = [[NSAppleScript alloc] initWithSource:command];
if( scriptObject == nil )
return false; "
But "scriptObject == nil" not happened.
I inspect memory leak by Xcode Instrument and find "NSAppleEventDescriptor coerceToDescriptorType" allocate lots of memory.
Could you help us how to free it?
This is how to activate app using AppleScript.
In Instrument, leak happend at "NSAppleEventDescriptor listDescriptor = [returnDescriptor coerceToDescriptorType:typeAEList];"
---- src below ----
NSString command = [NSString stringWithFormat:
@"try\n"
@"tell application "%@"\n"
@"activate\n"
@"delay 0.5\n"
@"tell application "System Events" to tell process "%@"\n"
@"tell (first window whose subrole is "AXStandardWindow")\n"
@"set fullScreen to value of attribute "AXFullScreen"\n"
@"if fullScreen = true then\n"
@"set value of attribute "AXFullScreen" to false\n"
@"end if\n"
@"end tell\n"
@"end tell\n"
@"end tell\n"
@"tell application "System Events"\n"
@"tell process "%@"\n"
@"tell window %d\n"
@"set {position, size} to {{%d,%d},{%d,%d}}\n"
@"end tell\n"
@"end tell\n"
@"end tell\n"
@"on error errMsg number errorNumber\n"
@"return "Error with number: " & errorNumber as text\n"
@"end try", ownerName, ownerName, ownerName, idx, (int)rect.origin.x, (int)rect.origin.y, (int)rect.size.width, (int)rect.size.height];
NSDictionary errorDict;
NSAppleEventDescriptor returnDescriptor = NULL;
NSAppleScript* scriptObject = [[NSAppleScript alloc] initWithSource:command];
if( scriptObject == nil )
return false;
returnDescriptor = [scriptObject executeAndReturnError: &errorDict];
NSAppleEventDescriptor *listDescriptor = [returnDescriptor coerceToDescriptorType:typeAEList];
NSString *result = @"";
for (NSInteger i=1; i<=[listDescriptor numberOfItems]; ++i) {
NSAppleEventDescriptor *stringDescriptor = [listDescriptor descriptorAtIndex:i];
if ( stringDescriptor.stringValue == nil ) continue;
result = [NSString stringWithFormat:@"%@%@", result, stringDescriptor.stringValue];
}
BRs,
YM
This is how to activate app using AppleScript.
NSString *command = [NSString stringWithFormat:
@"try\n"
@"tell application \"%@\"\n"
@"activate\n"
@"delay 0.5\n"
@"tell application \"System Events\" to tell process \"%@\"\n"
@"tell (first window whose subrole is \"AXStandardWindow\")\n"
@"set fullScreen to value of attribute \"AXFullScreen\"\n"
@"if fullScreen = true then\n"
@"set value of attribute \"AXFullScreen\" to false\n"
@"end if\n"
@"end tell\n"
@"end tell\n"
@"end tell\n"
@"tell application \"System Events\"\n"
@"tell process \"%@\"\n"
@"tell window %d\n"
@"set {position, size} to {{%d,%d},{%d,%d}}\n"
@"end tell\n"
@"end tell\n"
@"end tell\n"
@"on error errMsg number errorNumber\n"
@"return \"Error with number: \" & errorNumber as text\n"
@"end try", ownerName, ownerName, ownerName, idx, (int)rect.origin.x, (int)rect.origin.y, (int)rect.size.width, (int)rect.size.height];
NSDictionary* errorDict;
NSAppleEventDescriptor* returnDescriptor = NULL;
NSAppleScript* scriptObject = [[NSAppleScript alloc] initWithSource:command];
if( scriptObject == nil )
return false;
returnDescriptor = [scriptObject executeAndReturnError: &errorDict];
NSAppleEventDescriptor *listDescriptor = [returnDescriptor coerceToDescriptorType:typeAEList];
NSString *result = @"";
for (NSInteger i=1; i<=[listDescriptor numberOfItems]; ++i) {
NSAppleEventDescriptor *stringDescriptor = [listDescriptor descriptorAtIndex:i];
if ( stringDescriptor.stringValue == nil ) continue;
result = [NSString stringWithFormat:@"%@%@", result, stringDescriptor.stringValue];
}
return result;
}
It works for "Finder", "Evernote", "Google Chrome", and any other app.
Thanks for your suggestion.