Проблема 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