2012-06-05 3 views
1

У меня есть в значение, установленное до 10. Затем запустить NSTimer с этим кодом: [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(updateTimer) userInfo:nil repeats:YES]; Моя пустота выглядеть как этотInt не удается выполнить математику?

-(void)updateTimer { 
     timeLeft = timeLeft -0.01; 
     NSString *string = [NSString stringWithFormat:@"%i",timeLeft]; 
     [timer setString:string]; 
     NSLog(string); 

    } 

Я использую Coco2D, это не проблема В моей журнал он выходит как этот

2012-06-05 17:28:56.030 NumberPop[31291:10a03] 9 
2012-06-05 17:28:57.030 NumberPop[31291:10a03] 8 
2012-06-05 17:28:58.030 NumberPop[31291:10a03] 7 
2012-06-05 17:28:59.030 NumberPop[31291:10a03] 6 
2012-06-05 17:29:00.030 NumberPop[31291:10a03] 5 
2012-06-05 17:29:01.030 NumberPop[31291:10a03] 4 
2012-06-05 17:29:02.030 NumberPop[31291:10a03] 3 
2012-06-05 17:29:03.030 NumberPop[31291:10a03] 2 
2012-06-05 17:29:04.029 NumberPop[31291:10a03] 1 
2012-06-05 17:29:05.029 NumberPop[31291:10a03] 0 
2012-06-05 17:29:06.029 NumberPop[31291:10a03] 0 
2012-06-05 17:29:07.029 NumberPop[31291:10a03] 0 
2012-06-05 17:29:08.030 NumberPop[31291:10a03] 0 
2012-06-05 17:29:09.029 NumberPop[31291:10a03] 0 
2012-06-05 17:29:10.030 NumberPop[31291:10a03] 0 
2012-06-05 17:29:11.029 NumberPop[31291:10a03] 0 
2012-06-05 17:29:12.029 NumberPop[31291:10a03] 0 

0 продолжать идти на навсегда. Я так потерян, любая помощь?

+0

Я не вижу никаких условий для остановки. Если вы рассчитываете на то, что вычитание останавливается ровно на ноль, я бы сказал, что вы не понимаете, как работают числа с плавающей запятой. Вы не можете представить 0,1 точно как двоичный код больше, чем вы можете представлять 1/3 точно как десятичное. – duffymo

ответ

9

Так любопытно, почему вы пытаетесь вычесть 0,01 из int. Но когда вы это делаете, результат обрезается до int. Так что, если вы вычтите 0,01 из 9, вы получите 8.99, но int не может хранить 8.99, поэтому он хранится просто как 8. Как только вы дойдете до 0, он сделает то же самое. 0 - .01 = -0.01, которые усекаются до 0. Таким образом, вы всегда получите нуль от этого назначения.

Вместо этого, попробовать что-то вроде этого:

timeLeft = timeLeft - 1;

или даже лучше

timeLeft --;

либо из вышеперечисленных будет продолжать уменьшать число ниже нуля, например: -1, -2, -3 .... Предполагая, конечно, что это unsigned int (который int есть).

Кроме того, если вы хотите остановить таймер на ноль, вам необходимо аннулировать его, когда оставшееся время достигнет нуля. Смотрите здесь для получения дополнительной информации: https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/nstimer_Class/Reference/NSTimer.html#//apple_ref/occ/instm/NSTimer/invalidate

В принципе, сделать что-то вроде этого:

timeLeft --; 
if (timeLeft <= 0) [timer invalidate]; 

Там что-то важно, хотя понять. NSTimer не гарантирует, что он будет вызываться точно на указанном вами временном интервале. В принципе, он проверяет каждый цикл цикла, должен ли он запускаться, а затем делает это, если это необходимо. Но вы никогда не сможете запускать NSTimer чаще, чем запущенные циклы. Это означает, что если цикл цикла занимает больше времени, чем обычно, или ваш временной интервал слишком короткий, он может пропустить несколько интервалов до того, как он заработает. Поэтому подсчет «времени» путем уменьшения числа (как вы, кажется, делаете) не будет работать. Вместо этого вам нужно будет найти другой способ, например, установить стартовую переменную NSDate при запуске таймера, а затем проверить текущее время на каждом таймере против времени начала.

NSDate возвращает довольно мелкую детализацию в своих расчетах. Так что если вы берете дату начала, вы можете получить интервал времени, прошедший с этой даты, делая это:

NSTimeInterval interval = [[NSDate date] timeIntervalSinceDate:startDate];

NSTimeInterval является double.Таким образом, вы можете преобразовать его в строку, как это:

NSString *string = [NSString stringWithFormat:@"%f", interval];

или ограничить знаков после запятой:

NSString *string = [NSString stringWithFormat:@"%.2f", interval];

Это должно дать вам то, что вы ищете.

+0

Возможно ли тогда отобразить «прекрасный» таймер? – Sirens

+0

Зависит от того, как «прекрасный» вы ищете. Как правило, цикл запуска очень быстрый, если нет тяжелой графической (или иной) обработки. Но если это так, то ваш дисплей не может держать в любом случае, так что вопрос спорный. Нет смысла обновлять метку, индикатор выполнения и т. Д., Когда экран обновляется только один раз за цикл. Но я запускаю таймер на .01 без каких-либо проблем. Также поймите, что .01 - 100 кадров в секунду ..... это довольно высоко и вообще не нужно. –

+0

Что я имею в виду: могу ли я получить выход таймера, например, 10.900? – Sirens

Смежные вопросы