Re: What does "access" mean for NSAppleScript?
Re: What does "access" mean for NSAppleScript?
- Subject: Re: What does "access" mean for NSAppleScript?
- From: has <email@hidden>
- Date: Fri, 23 Feb 2007 20:32:23 +0000
Paul J. Lucas wrote:
The syntax of the sentence:
"You should only access (class name) from the main thread."
Implies that you shouldn't use anything involving the class--
methods or objects--from outside of the main thread.
I'm not asking for what it implies since inferences are subjective
and may not have any relationship to what's actually true. I'm
asking for what is actually true.
There are a couple of issues:
1. The AS language component is not fully thread-safe due to it
having some global state [1]. I believe cooperative threading is
possible if you know what you're doing, but preemptive threads are
right out.
2. By default, the AppleScript component uses AESendMessage to send
events and receive their replies on the main thread via the process's
default Mach port. Unlike the Carbon OSA or Cocoa OSAKit APIs,
NSAppleScript doesn't let you pass an alternative AESend function to
the AS component, so there's no way to specify your own Mach port for
receiving reply events on a non-main thread. From <http://
developer.apple.com/technotes/tn2002/tn2053.html#TN001208>:
Sending an AppleEvent from a thread other than the main thread, and
specifying kAEWaitReply, requires that the outgoing event specify a
reply mach port. For example:
mach_port_t port;
mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &port);
AEPutAttributePtr(&myEvent, keyReplyPortAttr, typeMachPort, &port,
sizeof(port));
AESendMessage(&event, &reply, kAEWaitReply, kAEDefaultTimeout);
mach_port_destroy(port);
See AE/AEMach.h for more information.
So if you're writing an attachable application (i.e. one that allows
users to attach AppleScripts to it; c.f. Folder Actions, Mail rules,
etc.), I think the safe and sensible thing would be to use
performSelectorOnMainThread:withObject:waitUntilDone: to do all your
NSAppleScript interactions on the main thread.
Alternatively, if you're just wanting an easy way to send events from
ObjC, I suggest you take a look at objc-appscript <http://
appscript.sourceforge.net/objc-appscript.html>. It's currently a work
in progress (so the usual warnings, caveats, etc. apply), and the
appscript layer doesn't yet provide a high-level API for specifying
event attributes. However, you can construct an appscript-style
command as normal (docs and examples are provided), then call its
AS_aemEvent method to obtain the underlying AEMEvent instance and use
its setAttributePtr:size:descriptorType:forKeyword: method [2] to add
your own Mach port.
HTH
has
[1] This is partly due to the design of the AppleScript interpreter,
and partly due to the design of the OSA architecture itself. I
suspect AppleScript wasn't designed with threaded use in mind, and
the OSA architecture was pretty much designed to suit AppleScript so
the original designers didn't bother to make it fully thread-safe
either (e.g. error state is stored at the component instance level,
not in the individual script which raised it, so unrelated scripts
can stomp on one another's error info). Unfortunately, making the OSA
thread-safe would also require non-backwards-compatible changes to
the current API, which doesn't help either. OSA's a great idea, but
the acutal execution is often less than stellar... I've been working
on a new Python OSA component this week, and the air's been blue at
times. :/
[2] setAttributePtr:size:descriptorType:forKeyword: is just a simple
wrapper around AEPutAttributePtr (see application.m).
--
http://appscript.sourceforge.net
http://rb-appscript.rubyforge.org
http://appscript.sourceforge.net/objc-appscript.html
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden