Таймер обратного отсчета с использованием NSTimer в формате "0:00" - PullRequest
0 голосов
/ 18 марта 2011

Я несколько дней изучал, как это сделать, и никто не может ответить.

Я создаю приложение с 5 таймерами в одном представлении.Мне нужно создать таймер, который отсчитывает от «15:00» (минуты и секунды), и еще один, который отсчитывает от «2:58» (минуты и секунды).15-минутный таймер не должен повторяться, но он должен останавливать все остальные таймеры, когда он достигает «00:00».Таймер «2:58» должен повторяться до тех пор, пока «15:00» или «Игровые часы» не достигнут 0. Прямо сейчас я удалил почти весь свой код и работаю над повторяющимся таймером «2:58»,или "rocketTimer."

Кто-нибудь знает, как это сделать?

РЕДАКТИРОВАТЬ 2: Мой симулятор даже не будет запускать приложение, поэтому в настоящее время я понятия не имею, работает ли таймер на самом деле или нет, но из моих предыдущих попыток это не сработало.Он не отображается в нужном мне формате, и он отсчитывает 2 (с последнего раза, когда он работал).Проблема также в том, что я не владею объективно-C.Я могу писать псевдокод весь день, как и все остальные, но я не могу поместить то, что я хочу, в код, потому что я не полностью понимаю NSTimer.

РЕДАКТИРОВАТЬ:

В моем выводе, я получаюэта ошибка "прекратить вызываться после выброса экземпляра 'NSException'"

и эта ошибка?

my error

Вот мой код:

    #import <UIKit/UIKit.h>


@interface FirstViewController : UIViewController {



    //Rocket Timer
    int totalSeconds;
    bool timerActive;
    NSTimer *rocketTimer;
    IBOutlet UILabel *rocketCount;

    int newTotalSeconds;
    int totalRocketSeconds;
    int minutes;
    int seconds;

}

- (IBAction)Start;



@end

и мой .м

    #import "FirstViewController.h"

@implementation FirstViewController

- (NSString *)timeFormatted:(int)newTotalSeconds
{

    int seconds = totalSeconds % 60; 
    int minutes = (totalSeconds / 60) % 60; 


    return [NSString stringWithFormat:@"%i:%02d"], minutes, seconds; 
}


-(IBAction)Start {

    newTotalSeconds = 178; //for 2:58

    newTotalSeconds = newTotalSeconds-1;

    rocketCount.text = [self timeFormatted:newTotalSeconds];


    if(timerActive == NO){

        timerActive = YES;
        newTotalSeconds = 178;

      [rocketTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerLoop) userInfo:nil repeats:YES];
    }

    else{

        timerActive = NO;
        [rocketTimer invalidate];
        rocketTimer = nil;

    }

}



-(void)timerLoop:(id)sender {

    totalSeconds = totalSeconds-1;

    rocketCount.text = [self timeFormatted:totalSeconds];


}

- (void)dealloc
{
    [super dealloc];

    [rocketTimer release];


}

- (void)didReceiveMemoryWarning
{
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.
}


- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.

    timerActive = NO;
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

@end

Ответы [ 3 ]

3 голосов
/ 21 марта 2011

Есть несколько проблем с вашим кодом!
Плохая новость заключается в том, что ни один из них не имеет отношения к аварии, которую вы видите.

Первая и самая очевидная проблема

На самом деле, вы никогда не остановите свой обратный отсчет!

После того, как вы запланировали таймер в Start, ваш timerLoop: -метод будет вызываться каждую секунду. Но вы забыли проверить, стал ли totalSeconds отрицательным ...

Вторая проблема

-(NSString *)timeFormatted:(int)newTotalSeconds не будет работать так, как вы ожидаете! На самом деле, я чертовски уверен, что XCode выдает предупреждение компилятора о том, что «Локальное объявление 'newTotalSeconds' скрывает переменную экземпляра" .
Попробуйте: в Start замените строку rocketCount.text = [self timeFormatted:newTotalSeconds]; на строку rocketCount.text = [self timeFormatted:42]; и установите точку останова после нее.

Третья проблема (на самом деле это пара проблем в одном месте)

Ваш dealloc совершенно неверен:
Во-первых, не самая лучшая идея - звонить после [super dealloc]. Во-вторых, «ты делаешь это неправильно»: учитывая твой Start -метод, у тебя нет таймера, поэтому ты не должен release. Вместо этого, если таймер все еще действителен, вам нужно его invalidate. Но это даже не станет проблемой, потому что, пока запланировано rocketTimer, ваш viewController не будет dealloc ed (если у вас нет ошибки в вашем управлении памятью где-либо еще). Я написал довольно полный пример , объясняющий это поведение в предыдущем посте.

Итак, что вызвало аварию?

Честно:
Понятия не имею!

Чтобы выяснить, что именно пошло не так, попробуйте добавить точку останова к -[NSException raise]. Кроме того, вы можете изменить функцию main в main.m следующим образом:

int main(int argc, char *argv[])
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    int response;
    @try {
        response = UIApplicationMain(argc, argv, nil, nil);
    } @catch (NSException *e) {
        NSLog(@"%@: %@\nCall-stack:\n%@", [e name], [e reason], [e callStackSymbols]);
        response = 1;
    }
    return response;
}

Это скажет вам, в каком методе ваша программа действительно потерпела крах.

1 голос
/ 20 марта 2011

Где находится экземпляр rocketTimer? Вы, кажется, упустили эту очень важную деталь. Я предполагаю, что rocketTimer неправильно сохраняется вашим кодом, и это вызывает сбой при попытке доступа к этому объекту после того, как он был освобожден.

Я бы предложил синтезировать ваше свойство и затем использовать встроенную настройку, установив self.rocketTimer при инициализации.

FirstViewController.h

@interface FirstViewController : UIViewController {
    NSTimer *rocketTimer;
}
@property (nonatomic, retain) NSTimer *rocketTimer;
- (IBAction)Start;
@end

FirstViewController.m

@implementation FirstViewController
@synthesize rocketTimer;
// test of implementation
// ...
0 голосов
/ 19 марта 2011

Если проблема в том, что он не повторяется, я бы позволил методу timerLoop проверить значение totalSeconds перед вычитанием. Если это 0, пусть он снова установит 178.

Если проблема кроется где-то еще, пожалуйста, сообщите нам, где, и дайте нам немного больше информации о том, в чем проблема и что вы уже пробовали в следующий раз.

...