views:

144

answers:

2

I'm using the scripting bridge to query iTunes from my cocoa application. Sometimes iTunes pops up a window (like if an ipod needs updating etc.) and while that popup window is open I can't get any information from iTunes. So if I request information from iTunes when it's in this state my application completely locks-up until that popup window is dismissed.

So I need some sort of mechanism where I can ask itunes something simple in a separate thread to see if I can get a response from it... and if that separate thread doesn't receive a response within a short period of time my main thread will just kill that thread and thus know not to query itunes at that particular time.

Any ideas how to create such a mechanism? I searched for ways to kill a thread but haven't found any.

A: 

Check out NSOperation/NSOperationQueue.

Joshua Nozzi
Thanks but I looked at that. NSOperation has the same "cancel" command as NSThread and thus the same problem... that if the "operation" is stuck it will never have a chance to check if it has been cancelled and thus never go away. I need a way to kill it, not cancel it.I have a solution but I don't like it. I run an applescript command using osascript in an NSTask. I create the task, run it in a separate thread, then check if the task isRunning from my main thread. If it's still running after a short amount of time I "interrupt" it which kills the task and I know not to query itunes.
regulus6633
I'd still like to find an NSThread solution because the NSTask using an osascript command has more overhead than is necessary, so any other solutions are welcome.
regulus6633
+1  A: 

Your problem is nothing to do with threads; it's that your timeout is too long. Whatever you're doing should fail after about a minute.

To fix this, send a setTimeout: message to the SBApplication object, passing the amount of time you want it to wait. The value is in ticks, of which there are exactly 60 per second.

(Some sources say 60.15, and Apple's own docs say “approximately” 60, but I just measured ten minutes' worth of TickCount, and the result of the division by 600 seconds is exactly 60.0. The code I used:
NSLog(@"Ticks per second: %f", (end - start) / (60.0 * numMinutes)); where end and start are results from TickCount.)

Peter Hosey
Wow Peter, thanks so much. That is it! I never waited long enough for the timeout to happen. I tested it without adjusting the value and it was taking 2 minutes to timeout. Then I took your suggestion and set the timeout to 300 ticks (i.e. 5 seconds) and sure enough it timed-out in 5 seconds and my app's interface was once again usable. This makes my life so much easier so thanks again for the tip!
regulus6633