IOS set same but different objects to one memory address - iphone

#interface ClassWithTimer : NSObject {
}
-(void) startTimer;
-(void) stopTimer;
#end
#implementation ClassWithTimer
NSTimer *up;
-(void) startTimer{
up = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(doSomething) userInfo:nil repeats:YES];
-(void) stopTimer{
[up invalidate];
}
- (void) doSomething{}
#end
then i do
- (IBAction)startTimers:(id)sender {
timer1 = [[ClassWithTimer alloc] initWithName:#"time1"];
timer2 = [[ClassWithTimer alloc] initWithName:#"time2"];
[timer1 startTimer];
[timer2 startTimer];
[timer1 stopTimer];
[timer2 stopTimer];
}
When i stop the timers i see that timer1 the same for timer2 and the invalidate method throw exception in [timer2 stopTimer] because this object invalidated at this moment.
I know that this is iOS policy but i can't find documentation for this.

Move
NSTimer *up;
into your .h file inside the interface block.

NSTimer needs to be an iVar, you are just declaring freely in the class allowing the two classes to share the same timer. Also you need to release the previous timer then retain the new one in startTimer.
#interface ClassWithTimer : NSObject {
NSTimer *up; //Declare iVar(instance variables) here
}
-(void) startTimer;
-(void) stopTimer;
#end
#implementation ClassWithTimer
-(void) startTimer{
[up invalidate];
[up release];
up = [[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(doSomething) userInfo:nil repeats:YES] retain];
-(void) stopTimer{
[up invalidate]; //Do these same this line
[up release]; //and this line in your dealloc
up = nil;
}
- (void) doSomething{}
#end

Related

Display each object in NSArray for 2 seconds

I have the following problem: I have an NSArray that contains 5 objects. I want to display each item for 2 seconds using NSTimer, and release the timer after displaying the last item in the array.
Country = [NSArray arrayWithObjects:#"Aus",#"India",#"Pak",#"China",#"Japan", nil];
cntcount = [Country count];
NSLog(#"concount=%i", cntcount);
[NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:#selector(startTime) userInfo:nil repeats:YES];
But I'm not getting another step. What should I do in the starttime() function? Please help!
//
// AppViewController.m
// NSTimerExample
//
#import "AppViewController.h"
#interface AppViewController ()
#end
#implementation AppViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
Country = [NSArray arrayWithObjects:
#"Aus", #"India", #"Pak", #"China", #"Japan", nil];
tempValue = 0;
NSTimer *popupTimer = [NSTimer scheduledTimerWithTimeInterval:2.0
target:self
selector:#selector(startTime:)
userInfo:nil
repeats:YES];
NSRunLoop *runner = [NSRunLoop currentRunLoop];
[runner addTimer:popupTimer forMode:NSDefaultRunLoopMode];
}
- (void)startTime:(NSTimer *)theTimer {
int cntcount = [Country count];
if(tempValue < cntcount) {
NSString *objectName = [Country objectAtIndex:tempValue];
NSLog(#"objectName=%#", objectName);
tempValue++;
} else {
[theTimer invalidate];
theTimer = nil;
// or you can reset tempValue to 0.
}
}
After displaying the last item I want to release timer as it is no longer needed, but I'm getting and EXC_BAD_ACCESS exception.
Do like this,
In .h
int tempValue;
In .m
tempValue=0;
NSTimer *popupTimer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:#selector(startTime:) userInfo:nil repeats:YES];;
NSRunLoop *runner = [NSRunLoop currentRunLoop];
[runner addTimer:popupTimer forMode: NSDefaultRunLoopMode];
In timer action method:
-(void)startTime:(NSTimer*)theTimer {
if(tempValue< Country.count) {
// Display array object eg: label.text=[Country objectAtIndex:tempValue];
tempValue++;
} else {
[theTimer invalidate];
theTimer=nil;
// or you can reset the tempValue into 0.
}
}
#import "AppViewController.h"
#interface AppViewController ()
#end
#implementation AppViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
Country=[[NSArray alloc]initWithObjects:#"Aus",#"India",#"Pak",#"China",#"Japan", nil];
tempValue=0;
NSTimer *popupTimer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:#selector(startTime:) userInfo:nil repeats:YES];;
NSRunLoop *runner = [NSRunLoop currentRunLoop];
[runner addTimer:popupTimer forMode: NSDefaultRunLoopMode];
}
- (void)startTime:(NSTimer*)theTimer {
if(tempValue< Country.count) {
NSString *objectname=[Country objectAtIndex:tempValue];
NSLog(#"objectname is %#",objectname);
tempValue++;
} else {
[theTimer invalidate];
theTimer=nil;
// or you can reset the tempValue into 0.
}
}
- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
#end
thanks to Tony and this code is working properly

How to stop/invalidate NStimer

I am using
[NSTimer scheduledTimerWithTimeInterval:0.1f
target:self
selector:#selector(update)
userInfo:nil
repeats:YES];
I want to stop calling this timer one.
viewDidDisappear
How can i do that? invalidate?
Declare NSTimer *myTimer in .h file.
Assign instance as tom said like this
myTimer = [NSTimer scheduledTimerWithTimeInterval:0.1f
target:self
selector:#selector(update)
userInfo:nil
repeats:YES];
Stop and Invalidate using this
- (void) viewDidDisappear:(BOOL)animated
{
[myTimer invalidate];
myTimer = nil;
}
Try this
viewController .h
NSTimer *timer;
viewcontroller.m
timer = [NSTimer scheduledTimerWithTimeInterval:1
target:self
selector:#selector(pollTime)
userInfo:nil
repeats:YES];
- (void) viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
[timer invalidate];
}
Yes, you would use the - (void)invalidate instance method of NSTimer.
Of course, to do that, you would have to save the NSTimer instance returned from [NSTimer scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:] into an ivar or property of your view controller, so you can access it in viewDidDisappear.
invalidate Method of NSTimer is use for stop timer
- (void) viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
[self.timer invalidate];
self.timer = nil;
}
If you are not ARC then don't forget [self.timer release];
For stopping or invalidating NSTimer first you have to create instance for NSTimer in Globally.
Timer=[NSTimer scheduledTimerWithTimeInterval:0.1f
target:self
selector:#selector(update)
userInfo:nil
repeats:YES];
after that try like this,
if (Timer != nil) {
[Timer invalidate];
Timer = nil;
}

No Known class method for selector 'myTimer'

Have basically two view controllers oneviewcontroller and mainviewcontroller. In oneviewcontroller defined myTimer. In mainviewcontroller i m trying to pause and resume myTimer using UIButton. But getting message No Known class method for selector 'myTimer'
In OneViewController defined NSTimer as myTimer
#property (nonatomic, retain) NSTimer *myTimer;
#synthesize myTimer;
- (void)viewDidLoad {
[self myTimerMethod];
[super viewDidLoad];
}
- (void)myTimerMethod{
NSLog(#"myTimerMethod is Called");
myTimer = [NSTimer scheduledTimerWithTimeInterval:2.4
target:self
selector:#selector(updateView:)
userInfo:nil
repeats:YES];
}
- (void)updateView:(NSTimer *)theTimer
{
if (index < [textArray count])
{
self.textView.text = [self.textArray objectAtIndex:index];
self.imageView.image = [self.imagesArray objectAtIndex:index];
index++;
}else{
index = 0;
}
I m trying to pause and resume myTimer from mainviewcontroller
In mainviewcontroller.h
#class OneViewController;
#property (strong, nonatomic) OneViewController *oneviewcontroller;
#synthesize oneviewcontroller = _oneviewcontroller;
-(void)playpauseAction:(id)sender {
if([audioPlayer isPlaying])
{
[sender setImage:[UIImage imageNamed:#"music.png"] forState:UIControlStateNormal];
[audioPlayer pause];
[[OneViewController myTimer] invalidate]; **\\No Known class method for selector 'myTimer'**
}else{
[sender setImage:[UIImage imageNamed:#"audiostop.png"] forState:UIControlStateNormal];
[audioPlayer play];
[[OneViewController myTimer] fire]; **\\No Known class method for selector 'myTimer'**
if(isFirstTime == YES)
{
self.timer = [NSTimer scheduledTimerWithTimeInterval:06.0
target:self
selector:#selector(displayviewsAction:)
userInfo:nil
repeats:NO];
isFirstTime = NO; } } }
how can i fix this error.
Thanks for help.
Instead of [[OneViewController myTimer] invalidate]; use [self.oneviewcontroller.myTimer invalidate];
Also, in OneViewController implementation, instead of myTimer = [NSTimer scheduledTimerWithTimeInterval:..... use self.myTimer = [NSTimer scheduledTimerWithTimeInterval:.....

Images not getting changed with NSTimer

This is my code
- (void)updateCounterImage:(NSTimer *)theTimer
{
static int count = 0;
count += 1;
int crb = 6 - count;
UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:#"ipad_game_timer_digit-%d.png", crb]];
if ( count == 6)
[timer release];
[countTime setImage:image];
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
[super viewDidLoad];
correctLevel.hidden = YES;
incorrectLevel.hidden = YES;
incorrectAnswer.hidden = YES;
correctAnswer.hidden = YES;
timer = [NSTimer scheduledTimerWithTimeInterval:1.0f
target:self
selector:#selector(updateCounterImage:)
userInfo:nil
repeats:NO];
}
#import <UIKit/UIKit.h>
#interface GameController : UIViewController
{
IBOutlet UIImageView *countTime;
NSTimer *timer;
}
#end
The problem is my imageView is not changing its image for countime.
You have set repeats to NO in the scheduledTimerWithTimeInterval which means the timer will only tick once.
You should write
timer = [NSTimer scheduledTimerWithTimeInterval:1.0f
target:self
selector:#selector(updateCounterImage:)
userInfo:nil
repeats:YES];

Unable to get NSTimer to work

Using NSTimer for my application in which I have to show countdown timer with initial timing equal to 100sec. It shows 99,then 98..96..94..92...86 and so on. But I want each sec to show up. Here is my code....
-(void)updateTimerLabel{
if (timeRemaining>0 ) {
timeRemaining=timeRemaining-1.0;
timerLabel.text=[NSString stringWithFormat:#"%.0f", timeRemaining];
countdownTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(updateTimerLabel) userInfo:nil repeats:YES];
}
}
Try following code
int i =100;
-(void)viewDidLoad
{
[super viewDidLoad];
[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(theActionMethod) userInfo:nil repeats:YES];
}
-(void)theActionMethod
{
if(i > 0)
{
NSString *str = [NSString stringWithFormat:#"%d",i];
lbl.text = str;
}
i--;
}
You are actually re-creating the timer every time your method gets called.
You should try leaving that outside and retaining it until you're finished with it.
#interface SomeClass
NSTimer * aTimer;
#end
#implementation
- (void)createTimer {
aTimer = [[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(updateTimerLabel) userInfo:nil repeats:YES] retain];
}
- (void)updateTimerLabel {
// do timer updates here
// call [aTimer release]
// and [aTimer invalidate]
// aTimer = nil;
// when you're done
}
#end
you have call updateTimerLabel outside the method.
ex:
-(void)viewDidLoad{timeRemaining=100.0;[self updateTimerLabel];countdownTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(updateTimerLabel) userInfo:nil repeats:YES];}
-(void)updateTimerLabel
{if (timeRemaining>0 )
{timeRemaining=timeRemaining-1.0;NSLog(#"%#",[NSString stringWithFormat:#"%.0f",timeRemaining]);}}