How to call a method once per second in objective-c - objective-c

My program has a loop that does calculation and drawing like 60 times a second. I want my movement action be executed only once a second, how do I do that with objective-c methods?

You can use
+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)seconds target:(id)target selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)repeats
For one second:
NSTimer *yourTastTimer = scheduledTimerWithTimeInterval:1 target:yourTarget selector:#selector(yourMethod) userInfo:nil repeats:YES;
You can check the documentation for NSTimer for details.
Edit
You may also want to check this answer.

If you are using Cocos2D for iphone you MUST NOT use the NSTimer.
Following the documentation, you should use the schedule:interval: method like that:
[self schedule: #selector(tick:) interval:1.0f];
- (void) tick: (ccTime) dt
{
//...
}

If your using a CCSprite ,they have a schedule method which might do the trick.
Basically do what for the main loop.
You could also keep a ticker in your main loop and check that this is the ticker%60==0.
Then call your movement action.
I read NSTimer is discouraged with cocos2d here.

Related

How to call a method every x seconds in Objective-C using NSTimer?

I am using Objective-C, Xcode 4.5.1 and working on an app for the iPhone.
I have a method A in which I want to call another method B to do a series of calculations every x seconds. In method A I start playing an audio file. Method B will monitor the audio every x seconds for the duration of the audio file.
I have found NSTimer as a potential solution, but am having a hard time getting it to work/understanding it.
I simply want to call Method B every x seconds and run its calculations, but NSTimer requires me to provide several things of which I'm not sure what I'm supposed to tell it.
[NSTimer scheduledTimerWithTimeInterval:(NSTimeInterval)
target:(id) select:(SEL) userInfo:(id) repeats:(BOOL)];
It is my understanding that at NSTimeInterval I provide the interval at which I want NSTimer to operate. But, how do I tell it to run Method B?
I have looked at example code, and am currently under the impression that I provide the method at the 'select:'. But, what do I write at the 'target:'? Why would I need a target? I tried entering 'self', but Xcode tells me:
Use of undeclared identifier 'self'
[NSTimer scheduledTimerWithTimeInterval:0.1 target:self
select:#selector(targetMethod:myVolumeMonitor()) userInfo:nil repeats:YES];
So, I figure 'self' is supposed to be a pointer to an object, but where do I want to point to?
Below is a simplification of my code:
MethodA()
{
//Start playing an audio file.
//NSTimer calling Method B, as long the audio file is playing, every x seconds.
}
MethodB()
{
//Do calculations.
}
I would be grateful if somebody could provide me with some answers/point me in the right direction! (:
Target is the recipient of the message named in select.
In Objective-C functions are not called. There are rather messages sent to objects. The Object internally refers to its symbol table and determines which of its methods is being called. That is a selector. Your selector is #selector(MethodB).
(BTW: you should start method names with lower case. "methodB" would be more appropriate here.)
This leads to the question: how to determine the object to which the message is sent? That is the target. In your case, it is simply self.
BTW: In this case the selector is expected to return void and accept an id, which is the id of the NSTimer object itself. That will come handy if you want the timer to stop firing based on some conditions according to your program logic.
Most important: Your selector is then methodB: rather than methodB.
- (void) methodA
{
//Start playing an audio file.
//NSTimer calling Method B, as long the audio file is playing, every 5 seconds.
[NSTimer scheduledTimerWithTimeInterval:5.0f
target:self selector:#selector(methodB:) userInfo:nil repeats:YES];
}
- (void) methodB:(NSTimer *)timer
{
//Do calculations.
}
try this
NSTimer *aTimer = [NSTimer timerWithTimeInterval:(x) target:self selector:#selector(timerFired:) userInfo:nil repeats:YES];
NSRunLoop *runner = [NSRunLoop currentRunLoop];
[runner addTimer:aTimer forMode: NSDefaultRunLoopMode];
[popUpImageView release];
- (void)timerFired:(NSTimer*)theTimer
{
if(condition)
{
[theTimer isValid]; //recall the NSTimer
//implement your methods
}
else
{
[theTimer invalidate]; //stop the NSTimer
}
}
If you look at your code and compared to the one below
[NSTimer scheduledTimerWithTimeInterval:0.1 target:self
select:#selector(targetMethod:myVolumeMonitor()) userInfo:nil repeats:YES];
self means that you are invoking a method in same instance of your class, in your example the method is myVolumeMonitor
[NSTimer scheduledTimerWithTimeInterval:0.1 target:self
selector:#selector(MethodB) userInfo:nil repeats:YES];
and you are good to go though
method be should look like this
- (void)MethodB:(NSTimer*)timer {
// do something
}
Well you are trying to call an normal C method, NSTimer can't to that.
The target is the an instance of the class on which to call the selector, this selector adn not select. The selector here is a SEL type which you can create with the #selector(METHOD_NAME) function.
For example this will call the handleTimer : ever 0.1 second: (For this example the AppDelegate is used):
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//SNIP, some code to setup the windos.
[NSTimer scheduledTimerWithTimeInterval:0.1f target:self selector:#selector(handleTimer:) userInfo:nil repeats:YES];
return YES;
}
- (void) handleTimer:(NSTimer *)timer {
// Hanlde the timed event.
}

Adding a delay within a loop

Is there any way to add a delay of a fraction of a second to a loop (e.g. A for loop). i.e. I would like a short delay after each iteration.
I know that cocos2d allows you to schedule selecters with a delay. But I am not sure how this could be used in this case.
I also know that sleep is costly and not advisable.
Any suggestions?
You should not use NSTimers in cocos2d. It will cause troubles if you want to have possibility to pause your game.
If you want to loop some action with fixed delay between iterations, you can freely use scedule:interval: method with needed delay.
[self schedule:#selector(methodToScedule) interval:yourDelay]
Or if you have to do random delay, you can use sequenses of cocos2d actions. For example
- (void) sceduleMethod
{
// do anything you want
ccTime randomDuration = // make your random duration
id delayAction = [CCDelayTime actionWithDuration: randomDuration];
id callbackAction = [CCCallFunc actionWithTarget:self selector:#selector(scheduleMethod)];
id sequence = [CCSequenece actionOne: delayAction actionTwo: callbackAction];
[self runAction: sequence];
}
in this case you must call your method only once. Then it will call itself with given delay.
You could use C's sleep function:
sleep(seconds);
But you could also look at UITimer, or possibly a block-based performSelector:withObject:afterDelay: method.
See this for more NSObject-based methods: https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html#//apple_ref/occ/instm/NSObject/performSelector:withObject:afterDelay

How to make a periodic call to a method in objective c?

if the question is not explained clearly please excuse me.
I'm developing an iphone Client-Server app, i created all the classes, instances and ect. I can even send get and parse the response too.. Anyway, now i need to make my method be called in a defined period of time(for instance, call it repeatly in 10 seconds). I googled a lot and also take a look at
NSDate but i couldn't solve.. Now, can anyone please help me how to handle this situation? Thank you very much
You can create and schedule an instance of NSTimer to call your method on a given time interval. See in particular the following convenience creation method:
+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)seconds target:(id)target selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)repeats
http://developer.apple.com/library/ios/#documentation/cocoa/reference/foundation/Classes/NSTimer_Class/Reference/NSTimer.html
Your best bet is to look into Grand Central Dispatch since you are going to want to run this in the background:
Use NSTimer mentioned above.
What you want is the NSObject method -performSelector:withObject:afterDelay:.
Click for docs.
If you have the method that it calls call this on itself again, you'll have a looping, self-firing delayed poll method.
I'd recommend checking a class variable to see if you really mean it each time, so you can turn it off from outside itself.
Grand Central Dispatch will create a different thread to run on. so if the timer method (shown below and suggested above) lags your app you will need to put the command on a separate thread.
NSTimer is what you should use though. for example if you want to repeat a method that is initiated from a button press you could do this
- (void)viewDidLoad
{
[super viewDidLoad];
[cameraControlButtonUp addTarget:self action:#selector(cameraControlButtonUpPressed)
forControlEvents:UIControlEventTouchUpInside];
}
-(IBAction)buttonDown:(id)sender{
NSInteger tag = [sender tag];
if (tag==1) {
buttonCounter=1;
timer = [[NSTimer scheduledTimerWithTimeInterval:.5 target:self selector:#selector(sendJoin) userInfo:nil repeats:YES]retain];
}
}
-(void)sendJoin
{
switch (buttonCounter) {
case 1:
[cClient userDigitalPushAndRelease:372];
break;
default:
break;
}
}
-(void)cameraControlButtonUpPressed
{
[timer invalidate];
}
that will repeat the command till the button is released. take in mind you need to link the ibaction with the button down event (only the button down event). as well as create timer in the .h and tag the button to 1 that you want to use this with.
for a more basic example; its quite simple. just create your method to call, timer and set repeat to YES. then call invalidate to stop it. i had to create a seperate method sendJoin because i couldnt get the numbers to pass correctly to the method. but if you dont have any parameters its even easier. just use the timer syntax to create it then invalidate it when ur done

iOS (objective C) version of ualarm()

I am looking for an Objective-C function to call a function to update the UI at a specified interval (between 2 and 5 seconds). Something that can be used (roughly) like this pseudocode:
array[String]; // already populated
function1(){
if (array.hasMoreElements()){
call function2() in x seconds;
}
}
void function2(){
update gui with next string in the array;
function1();
}
I simply can't use sleep() for x seconds, because the GUI will become unresponsive; and I can't create a new thread to update the GUI because the iOS UI elements are not thread safe.
I have researched ualarm(), but it is old and very crude, and someone told me that there is a similar utility in the iOS library; however I have not been able to find it.
You're talking about Obj-C but writing something like C pseudocode. If you're really writing normal Obj-C, the -performSelector:withObject:afterDelay is the general family you want that drops in here. (You can use "blocks" on iOS 4.x and above). For example in your use case:
- (void)displayNextString
{
if ([strings count] > 0) {
[self updateUIwithString:[strings objectAtIndex:0]];
[strings removeObjectAtIndex:0];
[self performSelector:#selector(displayNextString) withObject:nil afterDelay:2.0];
}
}
You may use NSTimer. This API fits perfectly what you want to do.
You can simply define a method like
-(void)updateUI {
//update interface
}
then do something like
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:interval target:self selector:#selector(updateUI) userInfo:nil repeats:YES];
This way the timer will continue call the method you set. Check the reference to see how to stop or invalidate the timer.

Objective C: constantly calling a function

I'm trying to make a pretty simple game and I'm stuck. Basically I want to make a UIImageView appear every 2 seconds. My problem is I can't keep track of cumulative time. Right now I have this:
NSDate *date = [NSDate date];
NSTimeInterval secondsSinceNow = [date timeIntervalSinceNow];
NSLog(#"date = %#", date);
NSLog(#"secondsSinceNow = %f", secondsSinceNow);
It's in my button function so its called when the user taps the button. It returns a decimal number always less than 1. I've tried it in the viewDidLoad method as well as it's own method but neither work.
I think it would work if its in it's own method that is check constantly, but I don't know how to do that.
In short, I need a timer/counter that updates every second.
#interface className
{
NSTimer * timer;
}
#property (nonatomic, retain) NSTimer * timer;
#end
#implementation className
#synthesize timer;
...
/*factory method was corrected here. should work without warnings by copying and pasting */
-(void) applicationDidFinishLaunching : (UIApplication *) application {
timer = [NSTimer scheduledTimerWithTimeInterval: 1.0 target:self selector:#selector(targetMethod:) userInfo:nil repeats: YES];
}
//define the target method
/*method was corrected because it needed parentheses around NSTimer */
-(void) targetMethod: (NSTimer *) theTimer {
NSLog(#"Me is here at 1 minute delay");
}
..
#end
taken from here
http://www.iphonedevsdk.com/forum/iphone-sdk-development/14403-nstimer-examples.html
If those first two lines are called immediately after each other, then it (should) always be less than a second. The date is being instantiated right there, and then the timeIntervalSinceNow is called immediately on it, when little/no time has occured between them. The goal is to make the date when first called, and then call the timeIntervalSinceNow on that to get times more than 0. However, this still has no creation of a updating timer as you want.
You could simply use an NSTimer to call a selector within your class at the required two second interval.
That said, you could possibly also make use of a CABasicAnimation to fade the opacity of the UIImageView, pending on the effect you require.