On Oct 7, 2010, at 9:48 AM, eveningnick eveningnick wrote:

> Actually, by "processing" i mean a lot of AppleScript calls, some of
> which return NSAppleEventDescriptors.
> I am not sure how it is happening under the hood (if someone could
> explain me...), but what i see is: i call
> NSAppleEventDescriptor *resultFromScript = [myapplescript
> executeAndReturnError];
> and then this call returns _only after_ the result is available (i.e.,
> the "return" operator in applescript has been called).

AppleScript. This raises the question whether AppleScript is thread safe and/or 
can be executed on secondary threads.
Most sources indicate and the most recent official document about thread safety 
<http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Multithreading/ThreadSafetySummary/ThreadSafetySummary.html%23//apple_ref/doc/uid/10000057i-CH12-SW1>
state that it is not thread safe and must be executed on the main thread only.


However, the official AppleScript release notes 
<http://developer.apple.com/library/mac/#releasenotes/AppleScript/RN-AppleScript/RN-10_6/RN-10_6.html%23//apple_ref/doc/uid/TP40000982-CH106-SW3>
 mention this:

Thread Safety
OSA and AppleScript are now thread-safe: they may be safely called on a 
non-main thread or from multiple threads without any locking in the client 
code. This also applies to NSAppleScript. This does not mean that AppleScript 
is totally concurrent: AppleScript uses locking to ensure that any single 
connection (a ComponentInstance) will only run on one thread at a time. Because 
of the size of the locking granularity, trying to manipulate the same script 
from multiple threads at once may still be subject to race conditions, and is 
not recommended.
Before using a scripting component on a background thread, developers should 
test the component’s “thread-safe” bit (cmpThreadSafe in 
theComponentDescription’s componentFlags.) Test the generic component before 
using OSA on a background thread, and then test the specific language component 
before using it on a background thread.
Scripting Additions and Thread Safety

Since a scripting addition can contain arbitrary code, a given addition command 
may or may not be thread-safe: offset of is, for example, butdisplay dialog is 
not. For compatibility, addition commands are presumed to be thread-unsafe, and 
will be executed on the main thread. Commands may be marked as thread-safe 
using an expanded Info.plist definition; see TN1164, Scripting Additions for 
Mac OS X, for details. Coercion handlers in scripting additions must be 
thread-safe; again, see TN1164 for details. Scripting addition developers 
should review and, if necessary, update their additions for thread-safety.

> Does my application register some "event listeners", that wait for
> AppleScripting server application (it is Microsoft Word) to post this
> event?

> Does that mean i will need the run loop?
When using AppleScript - I suspect you will need a runloop. But - please 
correct me if I'm wrong - I‘m pretty sure there is already a runloop for 
secondary threads when using a NSOperation which is scheduled through a 
NSOperationQueue. You can test whether a thread has a runloop:
    NSRunLoop* currentRunloop = [NSRunLoop currentRunLoop];

> Maybe it's better and easier
> to create the thread manually instead of using NSOperation?
No, I don't think so. An NSOperation and NSOperationQueue is quite convenient.
A custom NSOperation requires to override the main method only - and possibly 
init and dealloc methods.

As an additional feature, your custom operation may know for itself whether it 
can run in the background. This depends on the code it executes and what 
scripts it may run. So you can conditionally execute them in either a secondary 
thread or as an alternative in the main thread:

    if ([myOperation canRunInBackground])
        [self.operationQueue addOperation:myOperation];
    else
        [[NSOperationQueue mainQueue] addOperation:myOperation];  // this 
blocks the main thread for undetermined duration

You create the  operation queue which schedules operations on a secondary 
thread simply by invoking alloc and init.


How about making a custom NSOperation, overriding the methods -main (really 
only this method, and possibly init and dealloc) then testing whether it runs 
in a background thread?  :)


best

> Thank you
> 
>> It will be much easier to use a custom subclass of NSOperation for this kind 
>> of problem.
>> The operation's -main method should perform the transformation in a 
>> peace-wise manner and thereby repeatedly checking its cancelation state 
>> (-isCancelled method), like:
>> 
>> - (void) main {
>>    // runs on a secondary thread
>>    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
>>    ...
>>    while (![self isCancelled] && !done) {
>>        // transform a peace of data
>>        ...
>>    }
>> 
>>    [delegate fileTransformOperationDidFinish:self];
>> 
>>    [pool release];
>> }
>> 
>> You add the operation to a NSOperationQueue instance which schedules its 
>> operations onto a secondary thread. From your main thread you may then 
>> cancel the operation by sending it the -cancel message.
>> 
>> There are several ways to notify the application (or some object) when the 
>> task is finished. Using a delegate is safe and easy. You may consider to 
>> define a protocol for the delegate. The delegate method may also schedule 
>> its actual work to the main thread (via 
>> -performSelectorOnMainThread:withObject:waitUntilDone:) if this is necessary.
>> 
>> Just be careful when your task requires itself a runloop (e.g. using 
>> asynchronous NSURLConnection) - since there exists no (implicit) one when 
>> invoking an NSOperation's -main method on a secondary thread. Properly 
>> implementing this will require more elaborated code, though.
>> 

-------------------------------
Andreas Grosam
Eisenbahnstr. 27
D-79650 Schopfheim
phone:     +49 7622 1741
phone/Fax: +49 7622 697 639 0 
[email protected]




_______________________________________________

Cocoa-dev mailing list ([email protected])

Please 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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [email protected]

Reply via email to