Calling method with delay in main thread - ios

Hello guys I am in need.. Please help me out.
Below is the thread i run in my app which is called every .30delay.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
notification = [[NSNotificationCenter alloc] init];
notificationTimer = [NSTimer scheduledTimerWithTimeInterval:.30 target:self selector:#selector(notificationTimerFired:) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] run];
});
What i want is in method "notificationTimerFired" i am calling one more method and that is to be called say for 5sec interval.. How can i do that.. I tried to adding following code but at the 1st time it called for specified delay but later it calls continually with dispatch_async method is called. Please reply me I am badly in need
[NSTimer scheduledTimerWithTimeInterval:.30 target:self selector:#selector(notificationTimerFired:) userInfo:nil repeats:YES];

Folks, I found solution to my problem and it goes as follows
//run only once for specified delay
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
notification = [[NSNotificationCenter alloc] init];
notificationTimer = [NSTimer scheduledTimerWithTimeInterval:frequency*60
target:self
selector:#selector(repeateThreadForSpecificInterval:)
userInfo:nil
repeats:YES];
// Do any other initialisation stuff here
});
dispatch_once is the key which I was searching for. Any way thanks for your replies..

Related

NSTimer inside global queue is not called when the app is in the background

I want to run a selector using NSTimer which contains some network calls and some other tasks. I want to do that on global queue.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSTimer * myTimer=[[NSTimer alloc]init];
myTimer = [NSTimer timerWithTimeInterval:10*60 target:self selector:#selector(syncGroupAutomatically) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:myTimer forMode:NSRunLoopCommonModes];
[[NSRunLoop currentRunLoop] run];
});
-(void)syncGroupAutomatically
{
NSLog(#"Some Network calls and some other things\n");
}
If I run this code, it works fine when app is in foreground, but as soon as I press the home button it stops calling the syncGroupAutomatically method.
If anybody having any idea how to run this NSTimer even when app is in the background. Please help me.

calling method repeatedly after 3 seconds time interval in background

I have gone through many sites but still no answer.
I have a method suppose void xyz(), which will get called automatically from a View Controller after every 3 seconds.
I have no idea what to use, do I have to use NSThread or PerformSelector.
Call this method from ViewDidLoad method.ViewDidLoad will when your view will be appear in iPhone device or Simulator.
[NSTimer scheduledTimerWithTimeInterval:3.0f target:self selector:#selector(runMethod) userInfo:nil repeats:YES];
-(void)runMethod
{
}
Something like this
-(void)xyz{
[self performSelectorInBackground:#selector(xyz) withObject:nil];
}
- (void)viewDidLoad {
[self performSelector:#selector(xyz) withObject:nil afterDelay:0.3];
}
Use NSTimer
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:3.0f target:self selector:#selector(xyz) userInfo:nil repeats:YES];
You should use NSTimer as mentioned by #mokujin.
Please visit https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSTimer_Class/Reference/NSTimer.html

selector method of NSTImer called twice in beginBackgroundTaskWithExpirationHandler

In my beginBackgroundTaskWithExpirationHandler code block in '-applicationDidEnterBackground' method, I have nstimer implemented as follows:
UIBackgroundTaskIdentifier taskId = [application beginBackgroundTaskWithExpirationHandler:^{
timer = [NSTimer scheduledTimerWithTimeInterval:0.0 target:self selector:#selector(print:) userInfo:nil repeats:NO];
}];
And Eventhough its repeats:NO, 'print'method as the selector is called twice, which i can see through NSLog.
This timer hasn't be called from any where else than in applicationDidEnterBackground.
I assure you that there is nothing wrong with:
timer = [NSTimer scheduledTimerWithTimeInterval:0.0 target:self selector:#selector(print:) userInfo:nil repeats:NO];
Your 'print' method wil NOT be called twice. Your problem is with something else.
And another thing, a timer with a 0.0 time interval is rather pointless wouldn't you agree?

NSTimer not firing the selector

In ios5.0 with ARC, in my rootviewcontroller I call a method in a security manager object that is held by the app delegate. In that method I setup the timer as below
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self
selector:#selector(updateModel:) userInfo:str repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
However, this never fires the selector ie. updateModel: never gets called. What may be wrong? Is there another more efficient way I can do this without using NStimer?
Could also be a threading problem:
if
[NSThread isMainThread]
is false then start the timer like this:
dispatch_async(dispatch_get_main_queue(), ^{
timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(tick:) userInfo:nil repeats:YES];
})
You seem to be a bit mixed up with your timer variable.
You initialize a new timer but you aren't actually using it. Do you want to use the timer you initialized or do you want to you ApplicationDelegate.timer?
Here are the two possible solutions.
Option One (assuming that you have a class instance titled ApplicationDelegate and that it has a timer property):
ApplicationDelegate.timer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:#selector(updateModel:) userInfo:str repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:ApplicationDelegate.timer forMode:NSRunLoopCommonModes];
Option Two:
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:#selector(updateModel:) userInfo:str repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
I catch the same issue and I fire timer in main queue to solve it:
[NSURLConnection sendAsynchronousRequest:request queue:_operationQueue
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){
[self loopUpUpdateStart];
}];
-(void)loopUpUpdateStart{
dispatch_async(dispatch_get_main_queue(), ^{
_loopTimerForUpRevision =
NSTimer scheduledTimerWithTimeInterval: kNetworkLoopIntervalUpRev
target: self
selector: #selector(myCoolMethod)
userInfo: nil
repeats: YES];
TRACE(#"Start Up updates");
});
}
This line has several problems:
[[NSRunLoop currentRunLoop] addTimer:ApplicationDelegate.timer forMode:NSRunLoopCommonModes];
First, it should not be required at all. -scheduledTimerWithTimeInterval:... already adds the timer to the runloop. You do not need to add it again.
Second, the local variable timer is unrelated to the property ApplicationDelegate.timer (which is presumably nil at this point).
If you're talking to the application delegate so much that you've created something called ApplicationDelegate (a global? a macro?), you're talking to it too much. The application delegate is the delegate for the application; it assists in the application starting and stopping and responding to system events. The application delegate is not a place to store global variables. A timer is definitely not the kind of thing you'd fetch from another object in any case.

The selector of my NSTimer does not run. Why?

My code is:
-(void) timerRun{...}
-(void) createTimer
{
NSTimer *timer;
timer = [NSTimer timerWithTimeInterval:1.0
target:self
selector:#selector(timerRun)
userInfo:nil
repeats:YES];
}
viewDidLoad
{
[NSThread detachNewThreadSelector:#selector(createTimmer)
toTarget:self withObject:nil];
...
}
When I debug, the method createTimer runs ok, but the method does timerRun not run?
Just creating a timer doesn't start it running. You need to both create it and schedule it.
You're actually going to have to do slightly more work than that if you want it to run on a background thread. NSTimers attach to NSRunloops, which are the Cocoa form of an event loop. Each NSThread inherently has a a run loop but you have to tell it to run explicitly.
A run loop with a timer attached can run itself indefinitely but you probably don't want it to because it won't be managing autorelease pools for you.
So, in summary, you probably want to (i) create the timer; (ii) attach it to that thread's run loop; (iii) enter a loop that creates an autorelease pool, runs the run loop for a bit and then drains the autorelease pool.
Code will probably look like:
// create timer
timer = [NSTimer timerWithTimeInterval:1.0
target:self
selector:#selector(timerRun)
userInfo:nil
repeats:YES];
// attach the timer to this thread's run loop
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
// pump the run loop until someone tells us to stop
while(!someQuitCondition)
{
// create a autorelease pool
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// allow the run loop to run for, arbitrarily, 2 seconds
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:2.0]];
// drain the pool
[pool drain];
}
// clean up after the timer
[timer invalidate];
You have to schedule a timer for it to run. They get attached to a run loop, which in turn updates the timer as necessary.
You can either change createTimer to
[NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:#selector(timerRun)
userInfo:nil
repeats:YES];
or add
[[NSRunLoop currentRunLoop] addTimer:timer forModes:NSRunLoopCommonModes];
The method signature that you use in scheduledTimerWithTimeInterval:target:selector:userInfo:repeats: must have an argument for the NSTimer as it passes itself as an argument.
You should change your message signature to:
(void)timerRun:(NSTimer *)timer;
You don't need to do anything with the argument, but it should be there. Also in createTimer the selector will become #selector(timerRun:) as it now accepts an argument:
timer = [NSTimer timerWithTimeInterval:1.0
target:self
selector:#selector(timerRun:)
userInfo:nil
repeats:YES];

Resources