0

我正在使用 Applescript 在 Xcode 上编写 Mac App。
我做了一个不会永远停止的功能,但我无法停止它。
当我按下位于窗口上的按钮时,它就会启动。
因为此功能不会停止,所以按钮似乎永远被按下。
我必须使用“Command+Option+Escape”强制退出。(即使您进行此活动,此应用程序也可能不会停止。)
我想在功能启动之前释放按钮,并且我想通过按下另一个按钮来安全地停止此功能。
这是我的例子。要停止此操作,请按 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_

这是项目文件--> https://dl.dropboxusercontent.com/u/97497395/test.zip
对不起,我是日本人,英文写得不太好。

4

2 回答 2

2

基本上,您的应用程序界面在您的应用程序主线程上进行控制和更新。因此,如果您运行一些绑定主线程的代码,那么您的界面将没有机会自我更新,直到代码完成。因此,要修复您在后台线程中运行代码的问题,您的界面将能够自行更新。

我不知道您是否可以在 AppleScriptObjC 中执行此操作,因为我对它不太熟悉。这是我在objective-c中的做法。我创建了一个处理程序(someHandler),然后运行此代码。请注意,由于此处理程序未在具有自动生成的释放池的主线程中运行,因此您必须在处理程序中创建和排出释放池。

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

编辑:这是您询问的自动释放池。在引用计数环境中这样做......

-(void)someHandler {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    // do your stuff here

    [pool drain];
}

使用自动引用计数 (ARC),您可以这样做......

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

所以我不确定哪个适用于 AppleScriptObjC。一个快速的谷歌搜索出现了这篇文章

于 2013-08-10T20:23:59.870 回答
1

现在你的代码在循环,像界面这样重要的东西永远不会更新。如果您调用一个doEventFetch函数来运行所有排队的进程,那应该可以解决您的问题。只需在每个循环中调用一次:

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
于 2013-08-11T01:27:00.553 回答