I use performSelector_withObject_afterDelay to get an idle handler in ASObjC, but I guess it runs even in some “unexpected” circumstances: for example, if I start this loop
repeat 10 times
delay 1
end repeat
the “idle” handler doesn’t wait 10 seconds before running again. It seems it just ignores the “delay” instruction, while
repeat 10 times
do shell script "sleep 1"
end repeat
seems it behaves as expected. So, I won’t use delay, ok.
Now, the question is: is there any other thing performSelector_withObject_afterDelay ignores? I could use a sort of semaphore (setting a flag when entering/exiting my handlers) but it’s clearly too much onerous while the number of handlers grows… So, is there any way I can safely avoid using that semaphore?
I’m not clear what you are doing here. Where is the performSelector_withObject_afterDelay method? And where in the program is your repeat 10 times loop?
The problem is not the performSelector_withObject_afterDelay, it works as expected (it does what I want it to do and it stops doing it when I play with the UI controls). I noticed it just ignores the “delay” instruction so I’m wondering if there are other things it ignores.
I still can’t tell what you mean by “it just ignores the “delay” instruction” without knowing how the different elements of your code fit together. It’s hard to answer your question without knowing when the performSelector_withObject_afterDelay method is called, what its selector is and how that relates to your repeat 10 times loop.
This is my app (it does nothing useful, it just tests the idle handler)
script UntitledAppDelegate
property parent : class "NSObject"
on applicationWillFinishLaunching_(aNotification)
-- Insert code here to initialize your application before any files are opened
my performSelector_withObject_afterDelay_("myIdle:", 1, 1)
end applicationWillFinishLaunching_
on myIdle_(n)
--**
-- put what you normally put in your idle handler here
do shell script "date >> ~/Desktop/out.txt"
--**
my performSelector_withObject_afterDelay_("myIdle:", n, n)
end myIdle_
on myMethod_(sender) ---------------------- this is called by a button
repeat 10 times
delay 1 ------------ this is ignored
do shell script "sleep 1" ------------------------ this is NOT ignored
end repeat
end myMethod_
on applicationShouldTerminate_(sender)
-- Insert code here to do any housekeeping before your application quits
return current application's NSTerminateNow
end applicationShouldTerminate_
end script
Well, that’s some pretty weird logic there to have the performSelector_withObject_afterDelay method inside its own selector, so I don’t know if this really shows that it “ignores” a delay command. If you tell it to perform some function in x seconds it will do that regardless of any delay that happens after you execute the command but before the x seconds are up. Why the, do shell script “sleep 1”, doesn’t appear to be ignored, I don’t know, I’ve never used that command.
I don’t think you can draw many conclusions from this test.
The performSelector_withObject_afterDelay handler (almost) always works as expected: it runs when the app does nothing.
“delay 1” is ignored while “sleep 1” isn’t.
I’m only asking if this is the only scenario not working as expected, that’s all.
And, what I’m saying is that I can’t tell if this isn’t working as expected, because I don’t know what to expect when you recursively call the performSelector method from within its own selector – you would never (or shouldn’t any way) do that in a real program, so this “test” isn’t testing anything real.
on fauxIdle_(n)
--**
-- put what you normally put in your idle handler here
--**
set theResult to result
if class of theResult is in {integer, real} and theResult > 0 then set n to theResult
my performSelector_withObject_afterDelay_("fauxIdle:", n, n)
end fauxIdle_
Maybe Shane can explain this to me when he’s around, because I don’t understand it. What is “result” – I don’t see where he’s getting that. He answered this question in the context of replacing ASS’s idle “command” (did the questioner mean idle handler in stay open scripts here?). In any case this still seems like strange code to me – if you want a method that gets fired repeatedly until some condition is met, I would use the NSTimer method scheduledTimerWithTimeInterval_target_selector_userInfo_repeats_ and put the condition you want to test in the selector method where you would also invalidate the timer when your condition is met.
No: he just wanted to know how to replace the AS Studio idle handler which acts when the app does nothing and/or when the user doesn’t interact with it.
In a normal AS idle handler, if the last statement returns a number, it’s used as the delay value before idle is called again. This emulates that – the last result is used as the delay.
I assumed that’s what you were talking about, but since this is an ASOC piece of code and not an AS idle handler where is “result” coming from? I don’t see where you are getting that value.
The delay command should be avoided in ASObjC – it drives CPU usage through the roof and masks some other things. Use sleep if you must, or NSThread’s sleepForTimeInterval:, or better yet, an NSTimer.