0

I am coding Mac App on Xcode with Applescript.
I made a function that doesn't stop forever, but I can't stop it.
It starts when I push a button that is located on the window.
Because this function doesn't stop, the button appears pushed forever.
And I have to force quit with 'Command+Option+Escape'. (Even if you do this activity, this app may not be stop.)
I want release the button before the function starts, and I want to stop this function safely with pushing another button.
This is my example. To stop this, push the "Stop" button on Xcode.

property parent : class "NSObject" property mylabel : missing value on applicationWillFinishLaunching_(aNotification) -- Insert code here to initialize your application before any files are opened end applicationWillFinishLaunching_ on myStartButtonHandler_(sender) my myForeverFunction() end myStartButtonHandler_ on myStopButtonHandler_(sender) --How can I stop "myForeverFunction"? end myStopButtonHandler_ on myForeverFunction() set a to 0 repeat 100 times set a to a+1 mylabel's setStringValue_(a) delay 1 end repeat end myForeverFunction on applicationShouldTerminate_(sender) -- Insert code here to do any housekeeping before your application quits return current application's NSTerminateNow end applicationShouldTerminate_ 

This is the project file --> https://dl.dropboxusercontent.com/u/97497395/test.zip
Sorry I am Japanese, I can't write English very well.

2 Answers 2

2

Basically the interface of your application is controlled and updated on your apps main thread. Therefore if you run some code which ties up the main thread then your interface will not have a chance to update itself until the code is complete. So to fix that you run the code in a background thread and thus your interface will be able to update itself.

I don't know if you can do this in AppleScriptObjC because I'm not too familiar with it. Here's how I do it in objective-c. I create a handler (someHandler) and then run this code. Note that since this handler isn't run in the main thread which has an automatically generated release pool, you will have to create and drain a release pool in your handler.

[NSThread detachNewThreadSelector:@selector(someHandler) toTarget:self withObject:nil]; 

EDIT: Here's the autorelease pool you asked about. In a reference-counted environment do it this way...

-(void)someHandler { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // do your stuff here [pool drain]; } 

With Automatic Reference Counting (ARC) you would do it this way...

-(void)someHandler { @autoreleasepool { // do your stuff here } } 

So I'm not sure which applies to AppleScriptObjC. A quick google search turned up this post.

Sign up to request clarification or add additional context in comments.

8 Comments

I succeeded in stopping my function. NSThread's detachNewThreadSelector_toTarget_withObject_("someHandler", self, missing value) What you answered was the very thing I wanted to do. Thanks!
Actually, I couldn't succeed in stop the function in this way. I am finding another way...
property NSThread : class "NSThread" NSThread's detachNewThreadSelector_toTarget_withObject_("function", me, missing value) This code works successfully!
BTW, how can I create and drain a release pool? Could you write how to do it in native-Objc?
I got this error: [NSAutoreleasePool retain]: Cannot retain an autorelease pool
|
1

Right now your code is looping and looping and important things like the interface are never getting updated. If you call a doEventFetch function to run all of the queued processes, that should fix your problem. Just call it once every loop:

on doEventFetch() repeat tell current application's NSApp to set theEvent to nextEventMatchingMask_untilDate_inMode_dequeue_(((current application's NSLeftMouseDownMask) as integer) + ((current application's NSKeyDownMask) as integer), missing value, current application's NSEventTrackingRunLoopMode, true) if theEvent is missing value then exit repeat else tell current application's NSApp to sendEvent_(theEvent) end if end repeat end doEventFetch on loopFunc() repeat #Repeat stuff here... doEventFetch() end repeat end loopFunc 

2 Comments

Thanks, this code works in my sample, but my real project uses "delay 1200", so this code doesn't work in it. I don't know how to stop the function in "delay" command. But I'll use this code in another project. Thank you.
@usingsystem8 Instead of a delay you should use an NSTimer that will call the next function when it fires

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.