views:

165

answers:

1

I have an application that needs to update its display every minute or so. To achieve this I was using performSelector:withObject:afterDelay, calling the selector that most of the time just changes some text in a label based on a very simple (and quick) calculation.

[self performSelector:@selector(updateDisplay) withObject:nil 
     afterDelay:60];

Occasionally during an update, I have to go off and get some data from the web, and so I do that in another thread using detachNewThreadSelector. That all worked and the "performSelector after Delay" call completes in a tiny fraction of a second, and only runs once a minute. Despite this, and despite running fine on the simulator, the single button in the app is largely unresponsive, not responding to multiple stabs.

So, I had assumed peformSelector:afterDelay would not block, but I'm now wondering if it is blocking in some way? I even tried NOT doing the web-look-up incase this was somehow still impacting the responsiveness. No joy.

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

I then pushed it through shark to see if I could see anything obvious. From here I can see the web-lookup is the only thing taking any time, but it is only being done every couple of minutes, and then clearly not running on the main thread. The app itself is consuming a tiny fraction of 1% of the CPU (0.0000034%) over 20 minutes, so it just must be a blocking issue.

So, am I missing something about performSelector:afterDelay? What other common newbie mistakes might I be making. If it helps, although I've been developing applications for over 20 years, the previous 10 have been largely Java. Perhaps I have a Java assumption loaded :-) Essentially I have assumed the main thread is like the EDT (only do UI stuff on it, but keep everything else off it).

+1  A: 

How about trying performSelectorInBackground instead, and keeping a boolean semaphore/ or a queue of number of requests?

The use case has to be defined: If you mash at the button, should it do the request once, or repeatedly?

David Sowsy
There is no multiple request issue, it was not receiving the first request. I've done some heavy profiling, turning up nothing of any real value (except to indicate there should be no problem). I have now re-factored and used a timer rather than performSelector:afterDelay and it seems to have helped, I suspect there is some subtly of the run-loop at play here.
buggles