2011-09-07 21 views
5

Używam zagnieżdżonego NSTimer w aplikacji. Mam tu dwa problemy.jak rozstać NSTimer w celu-c

  1. Jak ponownie zainicjować licznik czasu w tej funkcji - (void)updateLeftTime:(NSTimer *)theTimer
  2. Jak zabić poprzedni licznik bo - (void)updateLevel:(NSTimer *)theTimer jest również wywołanie przez timer.

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    tmLevel=[NSTimer scheduledTimerWithTimeInterval:20.0f target:self selector:@selector(updateLevel:) userInfo:nil repeats:YES]; 

    tmLeftTime=[NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateLeftTime:) userInfo:nil repeats:YES]; 
} 

- (void)updateLevel:(NSTimer *)theTimer { 
    static int count = 1; 
    count += 1; 

    lblLevel.text = [NSString stringWithFormat:@"%d", count]; 

    tfLeftTime.text=[NSString stringWithFormat:@"%d",ANSWER_TIME]; 

    tmLeftTime=[[NSTimer alloc] init]; 
    tmLeftTime=[NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateLeftTime:) userInfo:nil repeats:YES]; 
    [self playMusic]; 

} 
- (void)updateLeftTime:(NSTimer *)theTimer { 
    static int timeCounter=1; 
    timeCounter+=1; 
    tfLeftTime.text=[NSString stringWithFormat:@"%d", (ANSWER_TIME-timeCounter)]; 
} 
+1

użyć metody unieważnić – Narayana

Odpowiedz

17
  • użytkowania [tmLevel invalidate] zrezygnować harmonogram czasowy.
  • Nie zapomnij ustawić tmLevel=nil natychmiast po (aby uniknąć stosując zmienną po czasomierz został nieplanowane i wydany przez Runloop)
  • Nie zapomnij unieważnia timer tmLevel przed utratą odniesienie do niego, a mianowicie zadzwoń [tmLevel invalidate] również przed przypisaniem nowego NSTimer do zmiennej tmLevel (albo poprzedni zegar będzie nadal prowadzony oprócz nowego)

Należy również zauważyć, że w kodzie masz bezużyteczne przydziały, które są ponadto stworzenie wyciek:

tmLeftTime=[[NSTimer alloc] init]; 
tmLeftTime=[NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateLeftTime:) userInfo:nil repeats:YES]; 

tutaj przydzielasz instancję NSTimer, przechowujesz tę instancję w tmLeftTime ... i natychmiast zapominasz o tej utworzonej instancji, aby zastąpić ją inną, utworzoną przy użyciu [NSTimer scheduledTimerWithTimeInterval:...]! Dlatego NSTimer utworzony przy użyciu [[NSTimer alloc] init] jest tracony i tworzy wyciek (ponieważ nigdy nie zostanie zwolniony).

Pierwsza linia jest całkowicie bezużyteczny, to trochę jak robiłeś

int x = 5; 
x = 12; // of course the value "5" is lost, replaced by the new value 
11

dodać następujące wiersze gdy u chcą, aby wyzerować stoper

[tmLeftTime invalidate]; 
tmLeftTime = nil; 

można również użyć

if ([tmLeftTime isValid]){ 
    // the timer is valid and running, how about invalidating it 
    [tmLeftTime invalidate]; 
    tmLeftTime = nil; 
} 
0

Jak o użyciu tylko jeden licznik zamiast 3 ?

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    tmLeftTime=[NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateLeftTime:) userInfo:nil repeats:YES]; 
} 

- (void)updateLevel { 
    static int count = 1; 
    count += 1; 

    lblLevel.text = [NSString stringWithFormat:@"%d", count]; 

    tfLeftTime.text=[NSString stringWithFormat:@"%d",ANSWER_TIME]; 

    [self playMusic]; 

} 
- (void)updateLeftTime:(NSTimer *)theTimer { 
    static int timeCounter=1; 
    timeCounter+=1; 
    tfLeftTime.text=[NSString stringWithFormat:@"%d", (ANSWER_TIME-timeCounter)]; 
    if (timeCounter >= ANSWER_TIME) { 
     timeCounter = 0; 
     [self updateLevel]; 
    } 
} 
0

Unieważnij timer za pomocą metody unieważniającej w metodzie updateLevel: i ponownie zaplanuj ten sam timer.

[tmLevel invalidate]; 
tmLevel = [NSTimer scheduledTimerWithTimeInterval:20.0f target:self selector:@selector(updateLevel:) userInfo:nil repeats:YES]; 

A jeśli chcesz wywołać updateTimeLeft: metoda nie trzeba do Alloc inny timer, że to duży wyciek ponieważ nigdy nie wydajemy te referencje.

tmLeftTime = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateLeftTime:) userInfo:nil repeats:YES]; 

I w Twojej updateTimeLeft: wystarczy ponownie zaplanować metodę zegara i ustawić warunek, w którym powinien się zatrzymać.

tmLeftTime = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateLeftTime:) userInfo:nil repeats:YES]; 
+0

Oh! Zrozumiałem, ale tak naprawdę wciąż jestem w środku, więc kod nie jest właściwy, muszę go wznowić po ukończeniu poziomu, a poziom ma 20 pytań. Po ukończeniu poziomu muszę pokazać reklamę.więc w ten sposób muszę go zrestartować. Dziękuję bardzo –