NSTimer countdown skips last second (not using last milliseconds) - iphone

I have a NS timer countdown which works perfectly fine thanks to your answers. However, my timer skips the last second so that it does not count the last 0s:99 ms . Is there anything wrong with my code? Best regards!
-(void) setTimer {
MySingletonCenter *tmp = [MySingletonCenter sharedSingleton];
tmp.milisecondsCount = 99;
tmp.secondsCount = 2;
tmp.countdownTimerGame = [NSTimer scheduledTimerWithTimeInterval:.01 target:self selector:#selector(timerRun) userInfo:nil repeats:YES];
}
-(void) timerRun {
MySingletonCenter *tmp = [MySingletonCenter sharedSingleton];
tmp.milisecondsCount = tmp.milisecondsCount - 1;
if(tmp.milisecondsCount == 0){
tmp.secondsCount -= 1;
if (tmp.secondsCount == 0){
//Stuff for when the timer reaches 0
[tmp.countdownTimerGame invalidate];
tmp.countdownTimerGame = nil;
tmp.lives = tmp.lives - 1;
NSString *newLivesOutput = [NSString stringWithFormat:#"%d", tmp.lives];
livesLabel.text = newLivesOutput;
if (tmp.lives == 0) {
timeLabel.text = #"0:00";
[self performSelector:#selector(stopped) withObject:nil afterDelay:2.0];
}
else {[self setTimer]; }
}
else
tmp.milisecondsCount = 99;
}
NSString *timerOutput = [NSString stringWithFormat:#"%2d:%2d", tmp.secondsCount, tmp.milisecondsCount];
timeLabel.text = timerOutput;
}

try to change this
-(void) setTimer {
MySingletonCenter *tmp = [MySingletonCenter sharedSingleton];
tmp.milisecondsCount = 100;// Change this from 99 to 100
tmp.secondsCount = 2;
tmp.countdownTimerGame = [NSTimer scheduledTimerWithTimeInterval:.01 target:self selector:#selector(timerRun) userInfo:nil repeats:YES];
}

For a start, get rid of
else {[self setTimer]; }
Otherwise you are restarting the timer every time that selector fires.
Next: swap these two around
tmp.secondsCount -= 1;
if (tmp.secondsCount == 0){
to
else {
tmp.secondsCount -= 1;
tmp.milisecondsCount = 99;
}
like so:
-(void) timerRun {
MySingletonCenter *tmp = [MySingletonCenter sharedSingleton];
tmp.milisecondsCount = tmp.milisecondsCount - 1;
if(tmp.milisecondsCount == 0){
if (tmp.secondsCount == 0){
//Stuff for when the timer reaches 0
[tmp.countdownTimerGame invalidate];
tmp.countdownTimerGame = nil;
tmp.lives = tmp.lives - 1;
NSString *newLivesOutput = [NSString stringWithFormat:#"%d", tmp.lives];
livesLabel.text = newLivesOutput;
if (tmp.lives == 0) {
timeLabel.text = #"0:00";
[self performSelector:#selector(stopped) withObject:nil afterDelay:2.0];
}
}
else
{
tmp.milisecondsCount = 99;
tmp.secondsCount -= 1;
}
}
NSString *timerOutput = [NSString stringWithFormat:#"%2d:%2d", tmp.secondsCount, tmp.milisecondsCount];
timeLabel.text = timerOutput;
}

Related

What is wrong with my countdown timer method?

Trying to make a countdown timer from a given NSTimeInterval, the label doesn't seem to be updating.
- (IBAction)startTimer:(id)sender{
timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(timerAction:) userInfo:nil repeats:YES];
}
- (void)timerAction:(NSTimer *)t {
if(testTask.timeInterval == 0){
if (self.timer){
[self timerExpired];
[self.timer invalidate];
self.timer = nil;
}
else {
testTask.timeInterval--;
}
}
NSUInteger seconds = (NSUInteger)round(testTask.timeInterval);
NSString *string = [NSString stringWithFormat:#"%02u:%02u:%02u",
seconds / 3600, (seconds / 60) % 60, seconds % 60];
timerLabel.text = string;
}
Issue is, you are decrementing the testTask.timeInterval inside the if(testTask.timeInterval == 0) , this condition never evaluates to true (because you set it to 10). That is why there is no change in the label.
You need to put that else case after the first if statement (Currently you placed it under second if statement).
You need to write your method like:
-(void)timerAction:(NSTimer *)t
{
if(testTask.timeInterval == 0)
{
if (self.timer)
{
[self timerExpired];
[self.timer invalidate];
self.timer = nil;
}
}
else
{
testTask.timeInterval--;
}
NSUInteger seconds = (NSUInteger)round(testTask.timeInterval);
NSString *string = [NSString stringWithFormat:#"%02u:%02u:%02u",
seconds / 3600, (seconds / 60) % 60, seconds % 60];
timerLabel.text = string;
}
I believe your if statements are nested incorrectly. Move your else statement to the outermost 'if' like so.
if(testTask.timeInterval == 0){
if (self.timer){
[self timerExpired];
[self.timer invalidate];
self.timer = nil;
}
} else {
testTask.timeInterval--;
}

Reset array after playing the game?

I made a quiz in iOS with xcode, what i have now is a quiz that generates 20 random answers out of an array, it controls the text of the labels when a button is pushed to check if the answer is correct. The answers are also random generated and i made sure that there weren't mulple answers with the same text. My problem is that when a question is asked, i change the text of an object in my array to "removed"; but when i push start again after i've done the quiz, my array has 20 objects with the string "remove"; my question is: How can I reset my array to it's normal objects? Here is my full code, ignore the comments but it's kind of a junk cause i'm new to ios programming:
//
// ViewController.m
// Mundo Grafia
//
// Created by Axel Lambregts on 2/10/12.
// Copyright (c) 2012 AxelNiels. All rights reserved.
//
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
// variabelen aanmaken
NSInteger intScore;
NSInteger intRandomMonument;
NSInteger intRandomAnswerPosition;
NSInteger intRandomAnswerA;
NSInteger intRandomAnswerB;
NSInteger intRandomAnswerC;
NSInteger intRandomAnswerD;
NSInteger intArrayEuropeLenght;
NSInteger intAmountOfQuestionsAsked;
NSString *scoreSpatie;
NSString *arrEurope[][2] =
{
{#"Eifel.jpg",#"Paris"},
{#"NotreDame.jpg",#"Paris"},
{#"ArcDeTriompheParis.jpg",#"Paris"},
{#"AtomuimBrussels.jpg",#"Brussels"},
{#"MannekePis.jpg",#"Brussels"},
{#"Colosseum.jpg",#"Rome"},
{#"TreviFountainRome.jpg",#"Rome"},
{#"SagradaFamilia.jpg",#"Barcelona"},
{#"SpanishSchoolMadrid.jpg",#"Madrid"},
{#"KremlinMoskou.jpg",#"Moskou"},
{#"MermaidKopenhagen.jpg",#"Copenhagen"},
{#"MonteCarloMonaco.jpg",#"Monaco"},
{#"AcropolisAthens.jpg",#"Athens"},
{#"ParlementBudapest.jpg",#"Budapest"},
{#"BuildingReykjavik.jpg",#"Reykjavik"},
{#"StatueKiev.jpg",#"Kiev"},
{#"PortOfEuropeLissabon.jpg",#"Lisbon"},
{#"ViewSanMarino.jpg",#"San Marino"},
{#"BridgesPrague.jpg",#"Prague"},
{#"MoskeeAnkara.jpg",#"Ankara"},
{#"TowerBridgeLondon.jpg",#"London"},
{#"BigBenLondon.jpg",#"London"},
{#"LondonEyeLondon.jpg",#"London"},
{#"BrandenburgerTor.jpg",#"Berlin"},
{#"ReichstagBerlin.jpg",#"Berlin"},
{nil,nil}
};
/*
NSArray *arrEurope = #[
#[#"Eifel.jpg",#"Paris"],
#[#"NotreDame.jpg",#"Paris"],
#[#"ArcDeTriompheParis.jpg",#"Paris"],
#[#"Eifel.jpg",#"Paris"],
#[#"NotreDame.jpg",#"Paris"],
#[#"ArcDeTriompheParis.jpg",#"Paris"],
#[#"AtomuimBrussels.jpg",#"Brussels"],
#[#"MannekePis.jpg",#"Brussels"],
#[#"Colosseum.jpg",#"Rome"],
#[#"TreviFountainRome.jpg",#"Rome"],
#[#"SagradaFamilia.jpg",#"Barcelona"],
#[#"SpanishSchoolMadrid.jpg",#"Madrid"],
#[#"KremlinMoskou.jpg",#"Moskou"],
#[#"MermaidKopenhagen.jpg",#"Copenhagen"],
#[#"MonteCarloMonaco.jpg",#"Monaco"],
#[#"AcropolisAthens.jpg",#"Athens"],
#[#"ParlementBudapest.jpg",#"Budapest"],
#[#"BuildingReykjavik.jpg",#"Reykjavik"],
#[#"StatueKiev.jpg",#"Kiev"],
#[#"PortOfEuropeLissabon.jpg",#"Lisbon"],
#[#"ViewSanMarino.jpg",#"San Marino"],
#[#"BridgesPrague.jpg",#"Prague"],
#[#"MoskeeAnkara.jpg",#"Ankara"],
#[#"TowerBridgeLondon.jpg",#"London"],
#[#"BigBenLondon.jpg",#"London"],
#[#"LondonEyeLondon.jpg",#"London"],
#[#"BrandenburgerTor.jpg",#"Berlin"],
#[#"ReichstagBerlin.jpg",#"Berlin"]
];
*/
//methode'start' wanneer er op de start-knop wordt gedrukt
-(IBAction)start{
[self NewQuestionEurope];
intAmountOfQuestionsAsked = 0;
//reset and show score
intScore = 0;
score.text = [NSString stringWithFormat:#"%d", intScore];
//make buttons and labels visible
Start.hidden = YES;
question.hidden = NO;
score.hidden = NO;
scoretext.hidden = NO;
imageContainer.hidden = NO;
answerA.hidden = NO;
answerB.hidden = NO;
answerC.hidden = NO;
answerD.hidden = NO;
answerA.textColor = [UIColor greenColor];
answerB.textColor = [UIColor greenColor];
answerC.textColor = [UIColor greenColor];
answerD.textColor = [UIColor greenColor];
clickButtonA.hidden = NO;
clickButtonB.hidden = NO;
clickButtonC.hidden = NO;
clickButtonD.hidden = NO;
GoodFalse.hidden = NO;
GoodFalse.text=#"Press a button to answer";
GoodFalse.textColor = [UIColor greenColor];
question.text = #"Where is this picture taken?";
}//einde start
-(IBAction)Reset{
score.text= #"gelukt";
}
-(IBAction)NewQuestionEurope{
if(intAmountOfQuestionsAsked == 19){
question.text = [#"Uw score is: "stringByAppendingString: [NSString stringWithFormat:#"%d", intScore]];
Start.hidden = NO;
question.hidden = NO;
score.hidden = YES;
scoretext.hidden = YES;
imageContainer.hidden = YES;
answerA.hidden = YES;
answerB.hidden = YES;
answerC.hidden = YES;
answerD.hidden = YES;
clickButtonA.hidden = YES;
clickButtonB.hidden = YES;
clickButtonC.hidden = YES;
clickButtonD.hidden = YES;
GoodFalse.hidden = YES;
Start.titleLabel.text = #"END";
}
else{
intAmountOfQuestionsAsked ++;
//Deze lus geeft aan intArrayEuropeLenght de waarde van hoeveel rijen de array bevat//
intArrayEuropeLenght = 0;
while (arrEurope[intArrayEuropeLenght][0] != NULL)
{
intArrayEuropeLenght++;
}
//score.text = [NSString stringWithFormat:#"%d", intScore];
scoreSpatie = [
[NSString stringWithFormat:#"%d", intScore]
stringByAppendingString:#"/"];
score.text = [
scoreSpatie
stringByAppendingString:[NSString stringWithFormat:#"%d", intAmountOfQuestionsAsked]
];
// Randoms genereren voor: 4 random antwoorden; 1 random afbeelding; een random positie om het juiste antwoord in te plaatsen
intRandomMonument = arc4random()%intArrayEuropeLenght;
intRandomAnswerA = arc4random()%intArrayEuropeLenght;
intRandomAnswerB = arc4random()%intArrayEuropeLenght;
intRandomAnswerC = arc4random()%intArrayEuropeLenght;
intRandomAnswerD = arc4random()%intArrayEuropeLenght;
intRandomAnswerPosition = arc4random()%4;
while(arrEurope[intRandomMonument][0] == #"removed"){
intRandomMonument = arc4random()%intArrayEuropeLenght;
}
//Random antwoorden maken
answerA.text = #"";
answerB.text = #"";
answerC.text = #"";
answerD.text = #"";
if(answerA.text = #""){
answerA.text = arrEurope[intRandomAnswerA][1];
}
if(answerB.text = #""){
answerB.text = arrEurope[intRandomAnswerB][1];
}
if(answerC.text = #""){
answerC.text = arrEurope[intRandomAnswerC][1];
}
if(answerD.text = #""){
answerD.text = arrEurope[intRandomAnswerD][1];
}
switch(intRandomAnswerPosition)
{
case 0: answerA.text = arrEurope[intRandomMonument][1];
break;
case 1: answerB.text = arrEurope[intRandomMonument][1];
break;
case 2: answerC.text = arrEurope[intRandomMonument][1];
break;
case 3: answerD.text = arrEurope[intRandomMonument][1];
};
//als er antwoorden hetzelfde zijn, voor de gelijke een random blijven maken tot ze niet hetzelfde zijn
if(
[answerA.text isEqualToString: answerB.text]||
[answerA.text isEqualToString: answerC.text]||
[answerA.text isEqualToString: answerD.text]
){
answerA.text = arrEurope[arc4random()%intArrayEuropeLenght][1];
};
if(
[answerB.text isEqualToString: answerA.text]||
[answerB.text isEqualToString: answerC.text]||
[answerB.text isEqualToString: answerD.text]
){
answerB.text = arrEurope[arc4random()%intArrayEuropeLenght][1];
};
if(
[answerC.text isEqualToString: answerA.text]||
[answerC.text isEqualToString: answerB.text]||
[answerC.text isEqualToString: answerD.text]
){
answerC.text = arrEurope[arc4random()%intArrayEuropeLenght][1];
};
if(
[answerD.text isEqualToString: answerA.text]||
[answerD.text isEqualToString: answerB.text]||
[answerD.text isEqualToString: answerC.text]
){
answerD.text = arrEurope[arc4random()%intArrayEuropeLenght][1];
};
//Laat de afbeelding zien van het gekozen monument (via random gekozen)
imageContainer.image = [UIImage imageNamed: arrEurope[intRandomMonument][0]];
}
}
//hier onder zit ergens een fout want hij geeft precies random juist en fout :)
//kan zijn dat het opgelost is vanaf we niet 2x dezelfde vragen hebben maar ik denk het niet.
//press buttonA
-(IBAction)AnswerA {
if([answerA.text isEqualToString: arrEurope[intRandomMonument][1]]){
GoodFalse.text = #"Correct!";
GoodFalse.textColor = [UIColor greenColor];
intScore ++;
}else {
GoodFalse.text=#"Wrong!";
GoodFalse.textColor = [UIColor redColor];
}
arrEurope[intRandomMonument][0] = #"removed";
[self NewQuestionEurope];
}
//press buttonB
-(IBAction)AnswerB {
if([answerB.text isEqualToString: arrEurope[intRandomMonument][1]]){
GoodFalse.text = #"Correct!";
GoodFalse.textColor = [UIColor greenColor];
intScore ++;
}else {
GoodFalse.text=#"Wrong!";
GoodFalse.textColor = [UIColor redColor];
}
arrEurope[intRandomMonument][0] = #"removed";
[self NewQuestionEurope];
}
//press buttonC (works)
-(IBAction)AnswerC {
if([answerC.text isEqualToString: arrEurope[intRandomMonument][1]]){
GoodFalse.text = #"Correct!";
GoodFalse.textColor = [UIColor greenColor];
intScore ++;
}else {
GoodFalse.text=#"Wrong!";
GoodFalse.textColor = [UIColor redColor];
}
arrEurope[intRandomMonument][0] = #"removed";
[self NewQuestionEurope];
}
//press buttonD
-(IBAction)AnswerD {
if([answerD.text isEqualToString: arrEurope[intRandomMonument][1]]){
GoodFalse.text = #"Correct";
GoodFalse.textColor = [UIColor greenColor];
intScore ++;
}else {
GoodFalse.text=#"Wrong!";
GoodFalse.textColor = [UIColor redColor];
}
arrEurope[intRandomMonument][0] = #"removed";
[self NewQuestionEurope];
}
//hier onder niets wijzigen
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
I see 2 options:
you call the init line again...
String *arrEurope[][2] =
{
{#"Eifel.jpg",#"Paris"},
{#"NotreDame.jpg",#"Paris"},...
Or you add a third row to your array and put the "removed" (i would call it "used") parameter there. In the last case you can then just iterate over your array again and put the "removed" back to "active"
Either make a copy of arrEurope on game start and restore to it when the game is restarted or use some other array to mark a question as removed. I would personally try to use option 2.

Saving NSInteger intScore when application is closed

I made an app with xcode 4, all code is in the main code file so i don't have more classes.
I have 3 views but only use one at the moment. Now in the game i save an integer as score, and at the end of the game it shows what your score is, but i wanted to know how i can let that int show up in a label in one of my other 2 views, and how i can keep it there when the application is restarted. I'm sorry of my bad english but i'm new to this objective C and iphone Apps. Thank You!
and how do i put something in an other viewcontroller, can't fine codefile
this is the code:
//
// ViewController.m
// Mundo Grafia
//
// Created by Axel Lambregts on 2/10/12.
// Copyright (c) 2012 AxelNiels. All rights reserved.
//
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
// variabelen aanmaken
NSInteger intScore;
NSInteger intRandomMonument;
NSInteger intRandomAnswerPosition;
NSInteger intRandomAnswerA;
NSInteger intRandomAnswerB;
NSInteger intRandomAnswerC;
NSInteger intRandomAnswerD;
NSInteger intArrayEuropeLenght;
NSInteger intAmountOfQuestionsAsked;
NSString *scoreSpatie;
NSString *arrEurope[][2] =
{
{#"Eifel.jpg",#"Paris"},
{#"NotreDame.jpg",#"Paris"},
{#"ArcDeTriompheParis.jpg",#"Paris"},
{#"AtomuimBrussels.jpg",#"Brussels"},
{#"MannekePis.jpg",#"Brussels"},
{#"Colosseum.jpg",#"Rome"},
{#"TreviFountainRome.jpg",#"Rome"},
{#"SagradaFamilia.jpg",#"Barcelona"},
{#"SpanishSchoolMadrid.jpg",#"Madrid"},
{#"KremlinMoskou.jpg",#"Moskou"},
{#"MermaidKopenhagen.jpg",#"Copenhagen"},
{#"MonteCarloMonaco.jpg",#"Monaco"},
{#"AcropolisAthens.jpg",#"Athens"},
{#"ParlementBudapest.jpg",#"Budapest"},
{#"BuildingReykjavik.jpg",#"Reykjavik"},
{#"StatueKiev.jpg",#"Kiev"},
{#"PortOfEuropeLissabon.jpg",#"Lisbon"},
{#"ViewSanMarino.jpg",#"San Marino"},
{#"BridgesPrague.jpg",#"Prague"},
{#"MoskeeAnkara.jpg",#"Ankara"},
{#"TowerBridgeLondon.jpg",#"London"},
{#"BigBenLondon.jpg",#"London"},
{#"LondonEyeLondon.jpg",#"London"},
{#"BrandenburgerTor.jpg",#"Berlin"},
{#"ReichstagBerlin.jpg",#"Berlin"},
{nil,nil}
};
/*
NSArray *arrEurope = #[
#[#"Eifel.jpg",#"Paris"],
#[#"NotreDame.jpg",#"Paris"],
#[#"ArcDeTriompheParis.jpg",#"Paris"],
#[#"Eifel.jpg",#"Paris"],
#[#"NotreDame.jpg",#"Paris"],
#[#"ArcDeTriompheParis.jpg",#"Paris"],
#[#"AtomuimBrussels.jpg",#"Brussels"],
#[#"MannekePis.jpg",#"Brussels"],
#[#"Colosseum.jpg",#"Rome"],
#[#"TreviFountainRome.jpg",#"Rome"],
#[#"SagradaFamilia.jpg",#"Barcelona"],
#[#"SpanishSchoolMadrid.jpg",#"Madrid"],
#[#"KremlinMoskou.jpg",#"Moskou"],
#[#"MermaidKopenhagen.jpg",#"Copenhagen"],
#[#"MonteCarloMonaco.jpg",#"Monaco"],
#[#"AcropolisAthens.jpg",#"Athens"],
#[#"ParlementBudapest.jpg",#"Budapest"],
#[#"BuildingReykjavik.jpg",#"Reykjavik"],
#[#"StatueKiev.jpg",#"Kiev"],
#[#"PortOfEuropeLissabon.jpg",#"Lisbon"],
#[#"ViewSanMarino.jpg",#"San Marino"],
#[#"BridgesPrague.jpg",#"Prague"],
#[#"MoskeeAnkara.jpg",#"Ankara"],
#[#"TowerBridgeLondon.jpg",#"London"],
#[#"BigBenLondon.jpg",#"London"],
#[#"LondonEyeLondon.jpg",#"London"],
#[#"BrandenburgerTor.jpg",#"Berlin"],
#[#"ReichstagBerlin.jpg",#"Berlin"]
];
*/
//methode'start' wanneer er op de start-knop wordt gedrukt
-(IBAction)start{
[self NewQuestionEurope];
intAmountOfQuestionsAsked = 0;
//reset and show score
intScore = 0;
score.text = [NSString stringWithFormat:#"%d", intScore];
//make buttons and labels visible
Start.hidden = YES;
question.hidden = NO;
score.hidden = NO;
scoretext.hidden = NO;
imageContainer.hidden = NO;
answerA.hidden = NO;
answerB.hidden = NO;
answerC.hidden = NO;
answerD.hidden = NO;
answerA.textColor = [UIColor greenColor];
answerB.textColor = [UIColor greenColor];
answerC.textColor = [UIColor greenColor];
answerD.textColor = [UIColor greenColor];
clickButtonA.hidden = NO;
clickButtonB.hidden = NO;
clickButtonC.hidden = NO;
clickButtonD.hidden = NO;
GoodFalse.hidden = NO;
GoodFalse.text=#"Press a button to answer";
GoodFalse.textColor = [UIColor greenColor];
question.text = #"Where is this picture taken?";
}//einde start
-(IBAction)Reset{
score.text= #"gelukt";
}
-(IBAction)NewQuestionEurope{
if(intAmountOfQuestionsAsked == 19){
question.text = [#"Uw score is: "stringByAppendingString: [NSString stringWithFormat:#"%d", intScore]];
Start.hidden = NO;
question.hidden = NO;
score.hidden = YES;
scoretext.hidden = YES;
imageContainer.hidden = YES;
answerA.hidden = YES;
answerB.hidden = YES;
answerC.hidden = YES;
answerD.hidden = YES;
clickButtonA.hidden = YES;
clickButtonB.hidden = YES;
clickButtonC.hidden = YES;
clickButtonD.hidden = YES;
GoodFalse.hidden = YES;
Start.titleLabel.text = #"END";
}
else{
intAmountOfQuestionsAsked ++;
//Deze lus geeft aan intArrayEuropeLenght de waarde van hoeveel rijen de array bevat//
intArrayEuropeLenght = 0;
while (arrEurope[intArrayEuropeLenght][0] != NULL)
{
intArrayEuropeLenght++;
}
//score.text = [NSString stringWithFormat:#"%d", intScore];
scoreSpatie = [
[NSString stringWithFormat:#"%d", intScore]
stringByAppendingString:#"/"];
score.text = [
scoreSpatie
stringByAppendingString:[NSString stringWithFormat:#"%d", intAmountOfQuestionsAsked]
];
// Randoms genereren voor: 4 random antwoorden; 1 random afbeelding; een random positie om het juiste antwoord in te plaatsen
intRandomMonument = arc4random()%intArrayEuropeLenght;
intRandomAnswerA = arc4random()%intArrayEuropeLenght;
intRandomAnswerB = arc4random()%intArrayEuropeLenght;
intRandomAnswerC = arc4random()%intArrayEuropeLenght;
intRandomAnswerD = arc4random()%intArrayEuropeLenght;
intRandomAnswerPosition = arc4random()%4;
while(arrEurope[intRandomMonument][0] == #"removed"){
intRandomMonument = arc4random()%intArrayEuropeLenght;
}
//Random antwoorden maken
answerA.text = #"";
answerB.text = #"";
answerC.text = #"";
answerD.text = #"";
if(answerA.text = #""){
answerA.text = arrEurope[intRandomAnswerA][1];
}
if(answerB.text = #""){
answerB.text = arrEurope[intRandomAnswerB][1];
}
if(answerC.text = #""){
answerC.text = arrEurope[intRandomAnswerC][1];
}
if(answerD.text = #""){
answerD.text = arrEurope[intRandomAnswerD][1];
}
switch(intRandomAnswerPosition)
{
case 0: answerA.text = arrEurope[intRandomMonument][1];
break;
case 1: answerB.text = arrEurope[intRandomMonument][1];
break;
case 2: answerC.text = arrEurope[intRandomMonument][1];
break;
case 3: answerD.text = arrEurope[intRandomMonument][1];
};
//als er antwoorden hetzelfde zijn, voor de gelijke een random blijven maken tot ze niet hetzelfde zijn
if(
[answerA.text isEqualToString: answerB.text]||
[answerA.text isEqualToString: answerC.text]||
[answerA.text isEqualToString: answerD.text]
){
answerA.text = arrEurope[arc4random()%intArrayEuropeLenght][1];
};
if(
[answerB.text isEqualToString: answerA.text]||
[answerB.text isEqualToString: answerC.text]||
[answerB.text isEqualToString: answerD.text]
){
answerB.text = arrEurope[arc4random()%intArrayEuropeLenght][1];
};
if(
[answerC.text isEqualToString: answerA.text]||
[answerC.text isEqualToString: answerB.text]||
[answerC.text isEqualToString: answerD.text]
){
answerC.text = arrEurope[arc4random()%intArrayEuropeLenght][1];
};
if(
[answerD.text isEqualToString: answerA.text]||
[answerD.text isEqualToString: answerB.text]||
[answerD.text isEqualToString: answerC.text]
){
answerD.text = arrEurope[arc4random()%intArrayEuropeLenght][1];
};
//Laat de afbeelding zien van het gekozen monument (via random gekozen)
imageContainer.image = [UIImage imageNamed: arrEurope[intRandomMonument][0]];
}
}
//hier onder zit ergens een fout want hij geeft precies random juist en fout :)
//kan zijn dat het opgelost is vanaf we niet 2x dezelfde vragen hebben maar ik denk het niet.
//press buttonA
-(IBAction)AnswerA {
if([answerA.text isEqualToString: arrEurope[intRandomMonument][1]]){
GoodFalse.text = #"Correct!";
GoodFalse.textColor = [UIColor greenColor];
intScore ++;
}else {
GoodFalse.text=#"Wrong!";
GoodFalse.textColor = [UIColor redColor];
}
arrEurope[intRandomMonument][0] = #"removed";
[self NewQuestionEurope];
}
//press buttonB
-(IBAction)AnswerB {
if([answerB.text isEqualToString: arrEurope[intRandomMonument][1]]){
GoodFalse.text = #"Correct!";
GoodFalse.textColor = [UIColor greenColor];
intScore ++;
}else {
GoodFalse.text=#"Wrong!";
GoodFalse.textColor = [UIColor redColor];
}
arrEurope[intRandomMonument][0] = #"removed";
[self NewQuestionEurope];
}
//press buttonC (works)
-(IBAction)AnswerC {
if([answerC.text isEqualToString: arrEurope[intRandomMonument][1]]){
GoodFalse.text = #"Correct!";
GoodFalse.textColor = [UIColor greenColor];
intScore ++;
}else {
GoodFalse.text=#"Wrong!";
GoodFalse.textColor = [UIColor redColor];
}
arrEurope[intRandomMonument][0] = #"removed";
[self NewQuestionEurope];
}
//press buttonD
-(IBAction)AnswerD {
if([answerD.text isEqualToString: arrEurope[intRandomMonument][1]]){
GoodFalse.text = #"Correct";
GoodFalse.textColor = [UIColor greenColor];
intScore ++;
}else {
GoodFalse.text=#"Wrong!";
GoodFalse.textColor = [UIColor redColor];
}
arrEurope[intRandomMonument][0] = #"removed";
[self NewQuestionEurope];
}
//hier onder niets wijzigen
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
NSUserDefaults *scores = [NSUserDefaults standardUserDefaults];
if (_points>[scores integerForKey :#"highscore"]) {
[_highScoresLabel setString:[NSString stringWithFormat:#"%d",_points]];
[scores setInteger:_points forKey:#"highscore"];
I'm using that code to show persistent highscore in one of my game.
to show in another UIViewController simply add this code where _higScoreLabel is the label ypu want the scores to be shown :
NSUserDefaults *scores = [NSUserDefaults standardUserDefaults];
NSString *_points = [scores integerForKey :#"highscore"];
[_highScoresLabel setString:[NSString stringWithFormat:#"%d",_points]];
As soon as you know what the user's final score was, write the integer to NSUserDefaults like:
[[NSUserDefaults standardUserDefaults] setInteger:intScore forKey:#"score"];
Then, in order to show the score integer in the other view controller, you'll need to just read the value from disk in viewDidLoad of the other viewController, and then set it in the label!
Since the value is already stored on disk, you don't even need to pass it as a parameter or set it as a property on the other viewcontroller, just read it from NSUserDefaults in viewDidLoad (or whatever/whereever method you need to set it).
So in the second viewcontroller, do:
- (void) viewDidLoad {
self.anotherLabel.text = [NSString stringWithFormat:#"%d", [defaults integerForKey:#"score"]];
}
// To save in pref
int highScore = yourGameScore;
[[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithInt:highScore] forKey:#"HighScore"];
[[NSUserDefaults standardUserDefaults] synchronize];
// To get saved value from pref
int highScore = [[[NSUserDefaults standardUserDefaults] objectForKey:#"HighScore"] intValue ];
here is similar question in stack..
Try using NSUserDefaults ,it will keep the value in memory until you forcefully remove it or you delete the app.
int Score = HighScore;
[[NSUserDefaults standardUserDefaults] setObject:Score forKey:#"anyKey"];
currentScoreLabel.text = [NSString stringWithFormat:#"%d",Score];
highScoreLabel.text=[NSString stringWithFormat:#"%d",[[NSUserDefaults standardUserDefaults] objectForKey:#"anyKey"]];

wait for a method to finish before starting another

assume that i have two sequential methods, methodA and methodB (methodB is called at the end of methodA) and i need to finish completely with the process of methodA before starting methodB :
-(void)methodA {
//do some very heavy computation here
[self methodB];
}
-(void)methodB {
//this method performs some animation
}
methodA requires alot of processing power and takes time to finish while methodB has animations. The animations are starting laggy at first and im guessing this has to do with the overhead of method A. So how can i make the second method start only after the first has finished completely?
this is the actual code:
the code is very messy and unorganized. there is alot of code that has been commented out so please ingore that. I test some things sometimes and then comment them out incase i need them later.
here is what is happening: it starts with (void)checkMoves method. This method calls either one of two similar methods which are
-(void)getMovesForJourney:(int)journey withRolls:(NSArray *)rolls or
-(void) getEntryMovesForJourney:(int)journey withRolls:(NSArray *)rolls
these methods are wrappers for a long recursive process (which is most probably where the multithreading is happening).
at the end of (void)checkMoves another method -(void)analyseMoves is called. This is also a heavy process.
and finally, at the end of -(void)analyseMoves the animation method -(void)move: is called. this last method is starting with a lag.
finally at the end of -(void)move: the process will start again until no more 'moves' are available.
the methods below are not in order so please refer to the description above to know whats going on.
-(void) checkMoves {
GameScene *game = [GameScene sharedGameScene];
CCLOG(#"start");
for (Stone *stone in stones) {
if (!stone.onBoard) {
if ([game EntryAvailable]) {
[self getEntryMovesForJourney:stone.journey withRolls:[game rollsAsIntegers]];
}
}
else {
[self getMovesForJourney:stone.journey withRolls:[game rollsAsIntegers]];
}
}
CCLOG(#"finish");
[self analyseMoves];
}
-(NSMutableArray *) otherPlayerLocations {
GameScene *game = [GameScene sharedGameScene];
Board *board = [game board];
Player *otherPlayer = [game playerOne];
NSMutableArray *locations = [[[NSMutableArray alloc] init] autorelease];
for (Stone *stone in otherPlayer.stones) {
if (stone.journey < 77) {
int location;
if (stone.onBoard)
location = [[board tileForATag:[self convertJourneyToTileTag:stone.journey]] bTag];
else
location = 0;
[locations addObject:[NSNumber numberWithInt:location]];
}
}
return locations;
}
-(void) analyseMoves {
if (moves.count > 0) {
NSMutableArray *killMoves = [[[NSMutableArray alloc] init] autorelease];
NSMutableArray *safeMoves = [[[NSMutableArray alloc] init] autorelease];
int mostThreatened;
float highestThreat = -1.0;
float lowestThreat = 100.0;
AIMove *safestMove;
//get kill and safe moves in seperate arrays
for (AIMove *move in moves) {
if (move.moveType == killMoveType)
[killMoves addObject:move];
else if (move.moveType == safeMoveType)
[safeMoves addObject:move];
// get highest threatened stone
//if (move.potThreat > highestThreat) {
// mostThreatened = move.journey;
// highestThreat = move.potThreat;
if (move.initThreat < lowestThreat) {
lowestThreat = move.initThreat;
safestMove = [move copy];
CCLOG(#"safest move assigned");
}
//}
}
//MOVE SELECTION:
//___________________________________
//choose best kill move
int killJourney;
if (killMoves.count > 0) {
//leave one move in killMoves with highest journey
killJourney = [[killMoves objectAtIndex:0] tileTag];
for (AIMove *killMove in killMoves) {
if (killMove.tileTag < killJourney)
[killMoves removeObject:killMove];
else
killJourney = killMove.tileTag;
}
}
//select correct move
if (killMoves.count > 0) {
[self move:[killMoves objectAtIndex:0]];
CCLOG(#"Kill move chosen");
}
else {
CCLOG(#"this is called!!!!");
CCLOG(#"safest move with initThreat: %i, potThreat: %i",safestMove.journey, safestMove.tileTag);
[self move:safestMove];
CCLOG(#"Success");
}
/*
else if (safeMoves.count > 0) {
[self move:[safeMoves objectAtIndex:0]];
CCLOG(#"safe move chosen");
}
else {
//temp random move generation
randomMove = CCRANDOM_0_1()*[moves count];
AIMove *move = [moves objectAtIndex:randomMove];
[self move:move];
CCLOG(#"Random move chosen");
}
*/
}
}
-(void) assignThreatLevel:(AIMove *)move {
NSArray *otherPlayerStones = [self otherPlayerLocations];
NSMutableArray *initThreats = [[NSMutableArray alloc] init];
NSMutableArray *potThreats = [[NSMutableArray alloc] initWithCapacity:4];
for (NSNumber *location in otherPlayerStones) {
//get threat levels for potential moves
if (move.tileTag > [location intValue]) {
int dif = move.tileTag - [location intValue];
CCLOG(#"dif: %i",dif);
//threat level conditions:
// 1 >> 5 = 70% of journey
// 6 >> 9 = 40% of journey
// 10 & 11 = 50% of journey
// 12 >> 24 = 20% of journey
// 25 && 26 = 50% of journey
// 27+ = 20% of journey
if (move.tileTag < 9) {
[initThreats addObject:[NSNumber numberWithFloat:0.0f]];
}
else if (dif >= 1 && dif <= 5) {
[initThreats addObject:[NSNumber numberWithFloat:k1to5]];
}
else if (dif >= 6 && dif <= 9) {
[initThreats addObject:[NSNumber numberWithFloat:k6to9]];
}
else if (dif == 10 || dif == 11) {
[initThreats addObject:[NSNumber numberWithFloat:k10to11]];
}
else if (dif >= 12 && dif <= 24) {
[initThreats addObject:[NSNumber numberWithFloat:k12to24]];
}
else if (dif == 25 || dif == 26) {
[initThreats addObject:[NSNumber numberWithFloat:k25to26]];
}
else if (dif > 26) {
[initThreats addObject:[NSNumber numberWithFloat:k27plus]];
}
//-------------------------------------
}
//get Threat levels for current positions
if (move.tileTag > [location intValue]) {
int dif = move.tileTag - [location intValue];
//threat level conditions:
// 1 >> 5 = 70% of journey
// 6 >> 9 = 40% of journey
// 10 & 11 = 50% of journey
// 12 >> 24 = 20% of journey
// 25 && 26 = 50% of journey
// 27+ = 20% of journey
if (move.journey < 8 || move.journey > 75)
[potThreats addObject:[NSNumber numberWithFloat:0.0f]];
else if (dif >= 1 && dif <= 5)
[potThreats addObject:[NSNumber numberWithFloat:k1to5]];
else if (dif >= 6 && dif <= 9)
[potThreats addObject:[NSNumber numberWithFloat:k6to9]];
else if (dif == 10 || dif == 11)
[potThreats addObject:[NSNumber numberWithFloat:k10to11]];
else if (dif >= 12 && dif <= 24)
[potThreats addObject:[NSNumber numberWithFloat:k12to24]];
else if (dif == 25 || dif == 26)
[potThreats addObject:[NSNumber numberWithFloat:k25to26]];
else if (dif > 26)
[potThreats addObject:[NSNumber numberWithFloat:k27plus]];
//-------------------------------------
}
}
float initThreat = 0.0f;
float potThreat = 0.0f;
for (NSNumber *number in initThreats) {
if ([number floatValue] > initThreat)
initThreat = [number floatValue];
}
for (NSNumber *number in potThreats) {
if ([number floatValue] > potThreat)
potThreat = [number floatValue];
}
move.initThreat = initThreat;
move.potThreat = potThreat;
[initThreats release];
}
-(void) move:(AIMove *)move {
CCLOG(#"Moves count: %i",[moves count]);
if ([moves count] > 0) {
BOOL isOtherStoneOnPreviousTile = NO;
int total;
if (move.tileTag > 8)
total = move.tileTag - move.journey;
else if (move.tileTag < 9 && move.journey > 8)
total = ((9-move.tileTag)+75) - move.journey;
else if (move.tileTag < 9)
total = move.tileTag - move.journey;
CCLOG(#"Total: %i",total);
GameScene *game = [GameScene sharedGameScene];
Board *board = [game board];
BoardTile *tile = [[game board] tileForBTag:move.tileTag];
CCSequence *sequence;
NSMutableArray *actions = [[[NSMutableArray alloc] init] autorelease];
id delay = [CCDelayTime actionWithDuration:0.5];
[actions addObject:delay];
if (move.journey > 0) {
for (int i = 1; i < total+1; i++) {
if (move.journey+i < 76)
tile = [board tileForBTag:move.journey+i];
else
tile = [board tileForBTag:9-((move.journey+i)-75)];
id moveAction = [CCMoveTo actionWithDuration:0.2 position:tile.position];
[actions addObject:moveAction];
}
}
else {
id moveAction = [CCMoveTo actionWithDuration:0.2 position:tile.position];
[actions addObject:moveAction];
}
// id moveFunc = [CCCallFunc actionWithTarget:self selector:#selector(moveMotion)];
//id moveAction = [CCMoveTo actionWithDuration:0.3 position:tile.position];
id killFunc = [CCCallFuncND actionWithTarget:self selector:#selector(killStonesForTile:data:) data:tile];
//id callfunc = [CCCallFunc actionWithTarget:self selector:#selector(move)];
[actions addObject:killFunc];
//[actions addObject:callfunc];
sequence = [CCSequence actionMutableArray:actions];
[actions removeAllObjects];
CGPoint exitPos = ccp(exitPosition.x-(completeStones*30),exitPosition.y-(completeStones*30));
id move2 = [CCMoveTo actionWithDuration:0.2f position:exitPos];
id sequence2 = [CCSequence actions:move2, nil];
Stone *stone = [self getStoneForJourney:move.journey];
//-
//------------------------------------------
//clean tracks
for (Stone *stone in stones) {
if (stone.journey == (move.tileTag - move.journey))
isOtherStoneOnPreviousTile = YES;
}
if (!isOtherStoneOnPreviousTile) {
BoardTile *prevTile = [board tileForBTag:[self convertJourneyToTileTag:move.journey]];
prevTile.occupiedBy = 0;
}
//===========================================
//-------------------------------------------
//set stone status
if (move.tileTag < 9 && stone.crossedEntry)
stone.journey = (9 - move.tileTag) + 75;
else
stone.journey = move.tileTag;
stone.onBoard = YES;
tile.occupiedBy = player2;
if (stone.journey > 8 && !stone.crossedEntry)
stone.crossedEntry = YES;
//============================================
if (stone.journey < 84)
[stone runAction:sequence];
else {
[stone runAction:sequence2];
completeStones++;
stone.isJourneyComplete = YES;
}
CCLOG(#"Stone Journey:%i",stone.journey);
NSArray *rollTypesArray = [move rollTypes];
[self removeRollTypes:rollTypesArray];
[moves removeAllObjects];
[game updateRollResults];
[self updateMoveAvailability];
}
else {
GameScene *game = [GameScene sharedGameScene];
[moves removeAllObjects];
[game nextTurn];
[game updateRollResults];
}
}
-(Stone *)getStoneForJourney:(int)journey {
Stone *theStone;
for (Stone *stone in stones) {
if (stone.journey == journey)
theStone = stone;
}
return theStone;
}
-(void)dealloc {
[moves release];
[rollTypes release];
[results release];
[super dealloc];
}
-(void)killStonesForTile:(id)sender data:(BoardTile *)tile {
GameScene *game = [GameScene sharedGameScene];
int tileTag;
Player *otherPlayer;
if (playerNumber == player1) {
tileTag = tile.aTag;
otherPlayer = [game playerTwo];
}
else {
tileTag = tile.bTag;
otherPlayer = [game playerOne];
}
CCArray *currentStones = [otherPlayer stones];
for (Stone *stone in currentStones) {
if (!stone.isJourneyComplete) {
int journey = stone.journey;
if (tileTag == tile.aTag) {
if (journey > 0 && [self convertJourneyToTileTag:journey] == tile.bTag) {
CCLOG(#"blue stone killed");
[self returnStoneToOrigin:stone];
}
}
if (tileTag == tile.bTag) {
if (journey > 0 && [self convertJourneyToTileTag:journey] == tile.aTag) {
CCLOG(#"gold stone killed");
[self returnStoneToOrigin:stone];
}
}
}
}
}
-(void)removeRollTypes:(NSArray *)theRollTypes {
GameScene *game = [GameScene sharedGameScene];
NSMutableArray *rolls = [game rolls];
for (NSNumber *roll in theRollTypes) {
NSUInteger index = [rolls indexOfObject:[game convertIntToRoll:roll]];
CCLOG(#"rolltypes count: %i",[theRollTypes count]);
CCLOG(#"roll integer: %i",[roll intValue]);
[rolls removeObjectAtIndex:index];
}
}
#pragma mark -
#pragma mark enumerations
- (NSArray*)getSums:(NSArray*)numbers {
NSMutableArray *result = [self getSumsHelper:numbers startingFrom:0];
[result removeObjectAtIndex:0];
return result;
}
- (NSMutableArray*)getSumsHelper:(NSArray*)numbers startingFrom:(NSUInteger)index {
/* (1) */
if (index >= [numbers count])
return [NSMutableArray arrayWithObject:[NSNumber numberWithFloat:0]];
/* (2) Generate all the subsets where the `index`th element is not included */
NSMutableArray* result = [self getSumsHelper:numbers startingFrom:index+1];
// NSSortDescriptor *mySorter = [[NSSortDescriptor alloc] initWithKey:#"floatValue" ascending:YES];
// [result sortUsingDescriptors:[NSArray arrayWithObject:mySorter]];
/* (3) Add all the cases where the `index`th element is included */
NSUInteger i, n = [result count];
float element = [[numbers objectAtIndex:index] floatValue];
for (i = 0; i < n; i++) {
float element2 = [[result objectAtIndex:i] floatValue];
float sum = element+element2;
BOOL numberPresent = NO;
for (NSNumber *number in result) {
if ([number floatValue] == sum)
numberPresent = YES;
}
if (!numberPresent)
[result addObject:[NSNumber numberWithFloat:sum]];
}
return result;
}
-(NSArray *) getCombsforNumbers:(NSArray *)numbers withTarget:(int)target{
NSMutableArray *partial = [[NSMutableArray alloc] init];
[partial addObject:[NSNumber numberWithInt:0]];
[results removeAllObjects];
NSArray *result = [self getCombsHelper:numbers target:target partial:partial];
NSUInteger minCount = [[result objectAtIndex:0] count];
NSUInteger index = 0;
NSMutableArray *combArray = [result objectAtIndex:0];
for (NSMutableArray *array in result) {
if ([array count] < minCount) {
minCount = [array count];
index = [result indexOfObject:array];
combArray = array;
}
}
//remove number 0 from array
[combArray removeObject:[NSNumber numberWithInt:0]];
return combArray;
}
-(NSMutableArray *) getCombsHelper:(NSArray *)numbers target:(int)target partial:(NSMutableArray *)partial {
int s = 0;
for (NSNumber *number in partial) {
s += [number intValue];
}
if (s == target) {
[results addObject:partial];
}
if (s >= target) {
return results;
}
for (int i = 0; i < [numbers count]; i++) {
NSMutableArray *remaining = [[[NSMutableArray alloc] init] autorelease];
int n = [[numbers objectAtIndex:i] intValue];
for (int j = i+1; j<[numbers count]; j++) {
[remaining addObject:[numbers objectAtIndex:j]];
}
NSMutableArray *partialRec = [[[NSMutableArray alloc] init] autorelease];
[partialRec addObjectsFromArray:partial];
[partialRec addObject:[NSNumber numberWithInt:n]];
[self getCombsHelper:remaining target:target partial:partialRec];
}
return results;
}
-(void) getMovesForJourney:(int)journey withRolls:(NSArray *)rolls {
GameScene *game = [GameScene sharedGameScene];
Board *board = [game board];
NSArray *sums = [self getSums:rolls];
for (NSNumber *number in sums) {
if ([number intValue]+journey <= 84) {
BoardTile *tile = [board tileForBTag:[self convertJourneyToTileTag:journey+[number intValue]]];
if (tile.isSafeTile) {
if (tile.occupiedBy != player1) {
AIMove *move = [AIMove moveWithJourney:journey tileTag:tile.bTag];
NSArray *theRollTypes = [[self getCombsforNumbers:rolls withTarget:[number intValue]] copy];
//Checking rolltypes, remove later
NSLog(#"%i = ",[number intValue]);
for (NSNumber *comb in theRollTypes) {
NSLog(#"%i",[comb intValue]);
}
NSLog(#"-----------");
//----------------------------------
move.moveType = safeMoveType;
move.initThreat = 0.0;
CCLOG(#"move initThreat: %f",move.initThreat);
[move setRollTypes:theRollTypes];
[moves addObject:move];
}
}
else {
AIMove *move = [AIMove moveWithJourney:journey tileTag:tile.bTag];
NSArray *theRollTypes = [[self getCombsforNumbers:rolls withTarget:[number intValue]] copy];
//Checking rolltypes, remove later
NSLog(#"%i = ",[number intValue]);
for (NSNumber *comb in theRollTypes) {
NSLog(#"%i",[comb intValue]);
}
NSLog(#"-----------");
//-----------------------------------
[move setRollTypes:theRollTypes];
//assing threat level
[self assignThreatLevel:move];
CCLOG(#"move initThreat: %f",move.initThreat);
//check for kill move
NSArray *otherPlayerPositions = (NSArray *)[self otherPlayerLocations];
for (NSNumber *location in otherPlayerPositions) {
if (move.tileTag == [location intValue])
move.moveType = killMoveType;
}
[moves addObject:move];
}
}
//int i = [number intValue];
//NSArray *combs = [self getCombsforNumbers:numbers withTarget:i];
}
}
-(void) getEntryMovesForJourney:(int)journey withRolls:(NSArray *)rolls {
GameScene *game = [GameScene sharedGameScene];
Board *board = [game board];
NSArray *sums = [self getSums:rolls];
for (NSNumber *number in sums) {
if ([number intValue]+journey <= 84) {
BoardTile *tile = [board tileForBTag:[self convertJourneyToTileTag:journey+[number intValue]]];
if (tile.isSafeTile) {
if (tile.occupiedBy != player1) {
NSArray *theRollTypes = [[self getCombsforNumbers:rolls withTarget:[number intValue]] copy];
BOOL containsEntry = NO;
for (NSNumber *rollType in theRollTypes) {
if ([rollType intValue] == 1) {
containsEntry = YES;
}
}
if (containsEntry) {
AIMove *move = [AIMove moveWithJourney:journey tileTag:tile.bTag];
//Checking rolltypes, remove later
NSLog(#"%i = ",[number intValue]);
for (NSNumber *comb in theRollTypes) {
NSLog(#"%i",[comb intValue]);
}
NSLog(#"-----------");
move.moveType = safeMoveType;
move.initThreat = 0.0;
CCLOG(#"move initThreat: %f",move.initThreat);
[move setRollTypes:theRollTypes];
[moves addObject:move];
//----------------------------------
}
}
}
else {
NSArray *theRollTypes = [[self getCombsforNumbers:rolls withTarget:[number intValue]] copy];
BOOL containsEntry = NO;
for (NSNumber *rollType in theRollTypes) {
if ([rollType intValue] == 1) {
containsEntry = YES;
}
}
if (containsEntry) {
AIMove *move = [AIMove moveWithJourney:journey tileTag:tile.bTag];
[move setRollTypes:theRollTypes];
//check for kill move
NSArray *otherPlayerPositions = (NSArray *)[self otherPlayerLocations];
for (NSNumber *location in otherPlayerPositions) {
if (move.tileTag == [location intValue])
move.moveType = killMoveType;
}
//assing threat level
[self assignThreatLevel:move];
[moves addObject:move];
//Checking rolltypes, remove later
NSLog(#"%i = ",[number intValue]);
for (NSNumber *comb in theRollTypes) {
NSLog(#"%i",[comb intValue]);
}
NSLog(#"-----------");
CCLOG(#"move initThreat: %f",move.initThreat);
[move setRollTypes:theRollTypes];
[moves addObject:move];
//----------------------------------
}
}
}
}
}
Technically, methodB is called after methodA is finished. In methodA you are apparently doing things that are backgrounded, meaning that the method finishes while some tasks are performed on another thread (or scheduled on the runloop). There's nothing we can say about this unless you do share the inner workings of methodA.

nstimer stop when touch the screen

I have a timer class, with a nstimer inside, who push notification to a uitableviewcontroller, and the notification object(value of the timer) is affected in a uitableviewcell. My problem is when I touch the screen to scroll, the timer stop, NSTimer don't start in a other thread? How I can fix this problem.
My timerClass
#import "timerEtape.h"
#import "FonctionUtile.h"
#import "Mission.h"
static timerEtape *sngTimerEtape = nil;
#implementation timerEtape
#synthesize repeatingTimerEtape;
#synthesize dateComp;
#synthesize questionCircuit;
#synthesize b_Pause;
+(timerEtape *) singletonTimer
{
#synchronized(self){
if (sngTimerEtape == nil )
{
sngTimerEtape = [[timerEtape alloc]init];
}
}
return sngTimerEtape;
}
-(id)init
{
self = [super init];
if (self != nil) {
dateComp = [[NSDateComponents alloc] init];
b_Pause = FALSE;
}
return self;
}
- (void)startTimer {
[repeatingTimerEtape invalidate];
NSString * temps;
if (questionCircuit) {
temps = [[Mission singletonMission].circuitTerrain valeurChampEtapeCircuitEnCours:#"et_temps_etape" :FALSE];
}
else {
temps = [[Mission singletonMission].histoireTerrain valeurChampQuestion:#"hi_temps_etape" :FALSE];
}
if (!b_Pause) {
[dateComp setHour:0];
[dateComp setMinute:[[FonctionUtile gauche:temps :2] intValue]];
[dateComp setSecond:[[FonctionUtile droite:temps :2] intValue]];
}
else {
b_Pause = FALSE;
}
self.repeatingTimerEtape = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(updateLabelTimerEtape:) userInfo:nil repeats:YES];
}
-(void)pause
{
self.b_Pause = TRUE;
[repeatingTimerEtape invalidate];
}
-(void)updateLabelTimerEtape:(NSTimer*)theTimer
{
if ([dateComp second] == 0) {
if ([dateComp minute] == 0) {
if ([dateComp hour] != 0) {
[dateComp setHour:[dateComp hour] -1];
[dateComp setMinute:59];
[dateComp setSecond:59];
}
else {
[repeatingTimerEtape invalidate];
[delegate performSelector:touchAction];
}
}
else {
[dateComp setMinute:[dateComp minute] -1];
[dateComp setSecond:59];
}
}
else {
[dateComp setSecond:[dateComp second] -1];
}
[[NSNotificationCenter defaultCenter] postNotificationName:#"rafraichirTimerEtape" object:[NSString stringWithFormat:#"%02d:%02d", [dateComp minute],[dateComp second]]];
}
-(void)setTarget:(id)target andAction:(SEL)action {
delegate = target;
touchAction = action;
}
-(void)dealloc
{
[dateComp release];
[repeatingTimerEtape release];
[super dealloc];
}
#end
and when I receive the notification in my uitableviewcontroller class
-(void)rafraichirTimerEtape:(NSNotification*)notification
{
[tempsRestant release];
tempsRestant = [[notification object]copy];
[table cellForRowAtIndexPath:[NSIndexPath indexPathForRow:2 inSection:0]].detailTextLabel.text = [notification object];
}
thanx
I have encountered with this problem before. In fact, NSTimer does not run in another thread, it always run in the thread which it is started. There is a runloop concept in iphone sdk, you should read it from here to understand timers. In this concept, you push some jobs into runloop and runloop implements them sequentially. The main thread is always a run loop and ui jobs are run there. So if you start your timer in the main thread, it will be affected by ui processing. You should start a new thread, configure it as a run loop and start your timers there.
Edit: Here is a sample code from the link that I posted. threadMain is the first function which the thread starts.
- (void) threadMain
{
NSRunLoop* myRunLoop = [NSRunLoop currentRunLoop];
// Create and schedule the timer.
[NSTimer scheduledTimerWithTimeInterval:0.1 target:self
selector:#selector(doFireTimer:) userInfo:nil repeats:YES];
NSInteger loopCount = 10;
do
{
// Run the run loop 10 times to let the timer fire.
[myRunLoop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]];
loopCount--;
}
while (loopCount);
}
if you want runloop to run infinitely, but terminate it with a condition, use this instead
BOOL shouldKeepRunning = YES; // global
NSRunLoop *theRL = [NSRunLoop currentRunLoop];
[NSTimer scheduledTimerWithTimeInterval:0.1 target:self
selector:#selector(doFireTimer:) userInfo:nil repeats:YES];
while (shouldKeepRunning && [theRL runMode:NSDefaultRunLoopMode
beforeDate:[NSDate distantFuture]]);