Проблема NSTimer

Поэтому я пытаюсь настроить основной таймер, но у меня ничего не получается. По сути, все, что я хочу, это запустить 60-секундный таймер, когда пользователь нажимает кнопку, и обновить метку с оставшимся временем (например, обратным отсчетом). Я создал свой ярлык и кнопку и соединил их в IB. Затем я создал IBAction для кнопки. Теперь, когда я попытался обновить метку на основе таймера, мое приложение испортилось. Вот мой код:

NSTimer *t = [NSTimer scheduledTimerWithTimeInterval: 1
                      target: self
                      selector:@selector(updateLabelDisplay)
                      userInfo: nil repeats:YES];

У меня также есть функция updateLabelDisplay, которая определяет, сколько раз таймер работал, а затем вычитает это число из 60 и отображает это число в метке обратного отсчета. Может кто-нибудь сказать мне, что я делаю не так?

2 ответа

Решение

Хорошо, для начала, проверьте это, если вы еще этого не сделали: Официальные документы Apple об использовании таймеров

Основываясь на вашем описании, вы, вероятно, хотите код, который выглядит примерно так. Я сделал некоторые предположения относительно поведения, но вы можете подойти по вкусу.

В этом примере предполагается, что вы хотите сохранить ссылку на таймер, чтобы вы могли приостановить его или что-то еще. Если это не так, вы можете изменить метод handleTimerTick таким образом, чтобы он принимал NSTimer* в качестве аргумента, и использовать его для аннулирования таймера после его истечения.

@interface MyController : UIViewController
{
  UILabel * theLabel;

  @private
  NSTimer * countdownTimer;
  NSUInteger remainingTicks;
}

@property (nonatomic, retain) IBOutlet UILabel * theLabel;

-(IBAction)doCountdown: (id)sender;

-(void)handleTimerTick;

-(void)updateLabel;

@end

@implementation MyController
@synthesize theLabel;

// { your own lifecycle code here.... }

-(IBAction)doCountdown: (id)sender
{
  if (countdownTimer)
    return;


  remainingTicks = 60;
  [self updateLabel];

  countdownTimer = [NSTimer scheduledTimerWithTimeInterval: 1.0 target: self selector: @selector(handleTimerTick) userInfo: nil repeats: YES];
}

-(void)handleTimerTick
{
  remainingTicks--;
  [self updateLabel];

  if (remainingTicks <= 0) {
    [countdownTimer invalidate];
    countdownTimer = nil;
  }
}

-(void)updateLabel
{
  theLabel.text = [[NSNumber numberWithUnsignedInt: remainingTicks] stringValue];
}


@end

Возможно, будет немного поздно опубликовать второй ответ на этот вопрос, но я искал подходящее место, чтобы опубликовать собственное решение этой проблемы. На случай, если это кому-нибудь пригодится, вот оно. Он срабатывает 8 раз, но, конечно, его можно настроить по своему усмотрению. Таймер освобождает себя, когда время истекло.

Мне нравится этот подход, потому что он держит счетчик интегрированным с таймером.

Чтобы создать экземпляр, вызовите что-то вроде:

SpecialKTimer *timer = [[SpecialKTimer alloc] initWithTimeInterval:0.1 
                                                         andTarget:myObject
                                                       andSelector:@selector(methodInMyObjectForTimer)];

Во всяком случае, вот файлы заголовка и метода.

//Header

#import <Foundation/Foundation.h>

@interface SpecialKTimer : NSObject {

    @private

    NSTimer *timer;

    id target;
    SEL selector;

    unsigned int counter;

}

- (id)initWithTimeInterval:(NSTimeInterval)seconds
                 andTarget:(id)t
               andSelector:(SEL)s;
- (void)dealloc;

@end

//Implementation

#import "SpecialKTimer.h"

@interface SpecialKTimer()

- (void)resetCounter;
- (void)incrementCounter;
- (void)targetMethod;

@end

@implementation SpecialKTimer

- (id)initWithTimeInterval:(NSTimeInterval)seconds
                 andTarget:(id)t
               andSelector:(SEL)s {

    if ( self == [super init] ) {

        [self resetCounter];

        target = t;
        selector = s;

        timer = [NSTimer scheduledTimerWithTimeInterval:seconds
                                                 target:self
                                               selector:@selector(targetMethod)
                                               userInfo:nil
                                                repeats:YES];

    }

    return self;

}

- (void)resetCounter {

    counter = 0;

}

- (void)incrementCounter {

    counter++;

}

- (void)targetMethod {

    if ( counter < 8 ) {

        IMP methodPointer = [target methodForSelector:selector];
        methodPointer(target, selector);

        [self incrementCounter];

    }

    else {

        [timer invalidate];
        [self release];

    }

}

- (void)dealloc {

    [super dealloc];

}

@end
Другие вопросы по тегам