I have the following class method to execute an AppleScript:
+ (NSString *) executeAppleScript:(NSString *) scriptToRun{
NSAutoreleasePool *thePool = [[NSAutoreleasePool alloc] init];
NSAppleScript *appleScriptObject = [[NSAppleScript alloc] initWithSource:scriptToRun];
NS开发者_运维知识库AppleEventDescriptor *objectReturned = [appleScriptObject executeAndReturnError:nil];
[appleScriptObject release];
appleScriptObject = nil;
NSString *charToReturn = [objectReturned stringValue];
if (charToReturn == nil ){
charToReturn = [NSString stringWithString:@"error"];
}
[charToReturn retain];
[thePool drain];
[charToReturn autorelease];
return charToReturn;
}
The problem is, this is leaking tons of memory. I admit fully that I do not completely understand memory allocations in Cocoa, so I was hoping someone might be able to explain to me why this is so leaky even with the autorelease pool.
Any help is greatly appreciated.
NSAppleEventDescriptor *objectReturned = [appleScriptObject executeAndReturnError:nil];
Don't ever do this. If you use this method wrong (unlikely) or give it a bad script (quite possible) or something doesn't work on the other application's end (very likely), you will be unable to find out what the problem is. Let the framework tell you what's wrong.
Plus, nil
is the wrong constant here. nil
is the null pointer for object pointer types; Nil
is for Class
values, and NULL
is for everything else.
charToReturn = [NSString stringWithString:@"error"];
This is already a string. You don't need to create another string with it.
The problem is, this is leaking tons of memory.
Have you verified with Instruments that you are actually leaking AppleScript-related objects that originate in this method?
I can't see anything in the method that looks wrong. The pool should be unnecessary, but your use of it is valid and correct.
You might try using the OSAKit, particularly its OSAScript class, instead. It's not documented, but the two classes' interfaces are pretty much the same.
精彩评论