Performselector not call in NSThread - iphone

I have a problem that i want to call a function when one of my functions that is running into a seperate thread comes to an end:
[NSThread detachNewThreadSelector:#selector(fetchFeaturedFreeApps) toTarget:self withObject:nil];
here is my fetchFeaturedFreeApps function
-(void)fetchFeaturedFreeApps
{
////all my code
[self performSelector:#selector(closeView) withObject:nil afterDelay:4.0];
}
My problem is that the close view methods doesnt run after the 4 seconds.
Hoew if i call the fetchFeaturedFreeApps method with perform selector then my closeview metod is called properly.
Your valuable help is highly appreciated.

You want to run any UI or view update code in a selector that runs on the main thread, not in a background thread. Use -performSelectorOnMainThread:withObject:waitUntilDone: and place a timer in that selector to fire after four seconds, which closes your view.

Related

Difference between calling a function in background and using calling a function in thread

I am not able to understand difference between calling a function in background like
[self performSelectorInBackground:#selector(getFriendFaceBookList) withObject:nil];
and calling the same function in a Thread :
[NSThread detachNewThreadSelector:#selector(getFriendFaceBookList) toTarget:self withObject:nil];
Which one is the best way to work in non ARC app.
Thanks
They're identical. See Documentation
performSelectorInBackground:withObject: The effect of calling this method is the same as if you called the detachNewThreadSelector:toTarget:withObject: method of NSThread with the current object, selector, and parameter object as parameters.
Hope it helps.

cancelPreviousPerformRequest from background thread issue

I have the following code, which is executed when a button is pressed:
[self performSelector:#selector(timeout:) withObject:nil afterDelay:30.0];
The issue comes in when I wanted to cancel this from a background thread:
[NSObject cancelPreviousPerformRequestsWithTarget:self];
I did this and it didn't cancel, it still calls timeout after 30 second. So my question, is there a way to cancel this from the background thread?
From the documentation, 'This method removes perform requests only in the current run loop, not all run loops.' That means that you have to call cancelPreviousPerformRequestsWithTarget on the main thread. Use performSelectorOnMainThread:withObject:waitUntilDone: from your thread to schedule a call to cancelPreviousPerformRequestsWithTarget on the main thread.
It's a roundabout way of doing things, but should work.
Edit to show example:
The easiest way is to use a helper method:
-(void)cancelTimeout
{
[NSObject cancelPreviousPerformRequestsWithTarget:self];
}
Then on your background thread call this when you want to cancel the timeout:
[self performSelectorOnMainThread:#selector(cancelTimeout) withObject:nil waitUntilDone:NO];
You can use NSTimer to call method after some time and invalidate if you want

UI update in selector

I perform this selector in my application:
- (void) doFilter:(UIButton*)button {
[activityIndicator startAnimating];
[self disableButtons];
// ...
// some actions
// ...
sleep(2);
[self enableButtons];
[activityIndicator stopAnimating];
}
when user clicks on button. activityIndicator is UIAtivityIndicatorView. But I don't see any activity indicators while this code is performing. How can I fix it?
Firstly, you should never ever use sleep on the main thread. It blocks your entire app and the user can't do anything for that time.
Secondly, the UI is not updated until your code returns control to the run loop. So whenever you call startAnimating and stopAnimating in the same method without returning to the run loop in between, you can be sure that nothing will happen in the UI (same with disableButtons and enableButtons).
Solution: call startAnimating and disableButtons. Then start the tasks you have to perform in the background so that the UI is not blocked. You can use NSOperation, performSelectorInBackground:..., Grand Central Dispatch etc. for that. Finally, when the long task is finished, have it call another method on the main thread which then calls stopAnimating and enableButtons.

performSelectorInBackground: on main thread

I know this is a wack question, but it is valid to performSelectorInBackground: on an iPhone apps' main thread? I am aware of performSelectorOnMainThread: but I was just wondering if performSelectorInBackground: can also be used on the main thread. My understanding is it cannot, because performSelectorInBackground: spawns a new thread each time.
performSelectorInBackground: essentially spawns a new thread, then performs the desired selector on that thread.
So, no it does not execute on the main thread. Ever.
I think that using performSelector:withObject:afterDelay: without a delay would be appropriate for your situation, because that does perform the selector on the main thread, except that it's performed in the next iteration of the current run loop:
[self performSelector:#selector(someMethod) withObject:nil afterDelay:0];

performSelectorOnMainThread works but performSelector doesn't why?

I have a selector and target, and calls the method like this
[target performSelectorOnMainThread:(SEL)selector withObject:nil waitUntilDone:FALSE];
But after I changed it to this, it doesn't work
[target performSelector:(SEL)selector withObject:nil afterDelay:0];
Any ideas?
I don't want to perform that task on the main thread because it lags the UI.
By doesn't work I mean that it simply doesn't call the method. I have it im debu mode in simulator and confirmed that it was not called.
I assume you're sending the message from another than the main thread. Cocoa just builds a run loop for the main thread, for other threads you have to build one yourself. The method performSelector:withObject:afterDelay: schedules the message for the next pass through the run loop. So if there is none, the message will not be sent.
For your case, why don't you just send [target performSelector:selector withObject:nil];? You dont need a run loop for that and the message will be sent immediately (on the same thread).