2010-07-10 5 views
3

그래서 기본 타이머를 설정하려고하는데 비참하게 실패하고 있습니다. 기본적으로 사용자가 버튼을 클릭 할 때 60 초 타이머를 시작하고 나머지 시간 (예 : 카운트 다운)으로 라벨을 업데이트하는 것이 좋습니다. 내 라벨과 버튼을 만들어 IB로 연결했습니다. 그런 다음 버튼에 대한 IBAction을 만들었습니다. 이제 타이머를 기반으로 라벨을 업데이트하려고 할 때 앱이 엉망이되었습니다. 나는 또한 타이머가 실행 된 후 60에서 해당 번호를 뺀 횟수를 결정하고 카운트 다운 라벨에 해당 번호를 표시하는 updateLabelDisplay 기능이NSTimer 문제

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

: 여기에 내 코드입니다. 아무도 내가 뭘 잘못하고 있다고 말할 수 있습니까? 당신이 아직없는 경우

+0

"내 앱이 고장 나면 확장 할 수 있습니까?" 관찰 할 수있는 것은 무엇입니까? –

+0

또한 설명에 따르면 낮은 경계 (60에서 카운트 다운)가있는 것처럼 들리므로 아마도 어느 시점에서 타이머를 무효화하려고 할 것입니다. 이것이 문제는 아니지만 나중에 타이머를 참조하여 무효화하는 것이 좋습니다. 어쩌면 나중에 코드에서이 작업을 수행하고있을 수도 있지만, 처음에는 로컬 변수를 사용했기 때문에 나중에 두통을 줄이기 위해 언급 할만한 가치가 있다고 생각했습니다. –

+0

기본적으로 레이블은 업데이트되지 않습니다. – Roosh

답변

11

좋아, 그럼 우선,이 체크 아웃 : 당신의 설명을 바탕으로

Official Apple Docs about Using Timers, 당신은 아마 다음과 같은 형태의 코드를합니다. 나는 행동에 관한 몇 가지 가정을했지만, 맛에 맞게 할 수 있습니다.

이 예제에서는 타이머에 대한 참조를 보류하여 일시 중지 할 수 있다고 가정합니다. 그렇지 않은 경우 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 
+3

더 나은 방법은 틱 카운터를 사용하는 대신 시간 간격을 사용하여 경과 시간을 기준으로 레이블을 업데이트하는 것입니다. runloops의 특성상 타이머가 작동하는 시점에 대한 정밀도는 보장되지 않습니다. 그러나 위 코드는 샘플 코드에 충분합니다. –

+0

정말 고마워요! 한 가지 질문 만해도 doCountdown이 내 UIButton에 연결될 것입니다. – Roosh

+0

맞습니다. doCountdown : 버튼에 연결하는 작업입니다. –

1

이 질문에 대한 두 번째 답변을 게시하는 것이 조금 늦을 수 있지만이 문제에 대한 내 자신의 솔루션을 게시 할 수있는 좋은 곳을 찾고있었습니다. 여기 누군가에게 사용의 경우입니다. 그것은 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 
+0

자기 자신에 대해'-dealloc'을 호출하는 것이 잘못되었습니다. http://stackoverflow.com/questions/3819603/suicide-objective-c-objects-calling-their-own-dealloc-methods-on-themselves를 참조하십시오. – SK9