2011-09-07 35 views
5

我在應用程序中使用嵌套的NSTimer。我在這裏有兩個問題。如何計劃NSTimer在objective-c

  1. 如何在這個函數- (void)updateLeftTime:(NSTimer *)theTimer
  2. 如何殺死以前的計時器,因爲- (void)updateLevel:(NSTimer *)theTimer也被調用計時器重新開始計時。

- (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

使用無效方法 – Narayana

回答

17
  • 使用[tmLevel invalidate]取消計時器的時間表。
  • 不要忘記設置tmLevel=nil後立即(避免使用可變計時器已經計劃外和由Runloop釋放後)
  • 不要忘記失去對它的引用之前無效tmLevel定時器,即調用[tmLevel invalidate]還分配新的NSTimer到tmLevel變量之前(或者以前的計時器會繼續除新的運行)

還要注意的是,在你的代碼中有沒用的分配被而且創建泄漏:

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

這裏您分配一個NSTimer實例,將這個實例存儲在tmLeftTime中,然後立即忘記創建的實例,以便用另一個替換它,使用[NSTimer scheduledTimerWithTimeInterval:...]創建! 因此,使用[[NSTimer alloc] init]創建的NSTimer丟失,並且正在創建泄漏(因爲它永遠不會被釋放)。

你的第一行是完全無用的,這有點像你在做

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

添加以下線路時ü要復位定時器

[tmLeftTime invalidate]; 
tmLeftTime = nil; 

你也可以使用

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

大約只用一個定時器,而不是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

使用updateLevel方法中的invalidate方法使計時器失效,並重新計劃相同的計時器。

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

如果你想撥打updateTimeLeft:你不需要的Alloc另一個定時器的方法,這是一個大的泄漏,因爲你永遠不會釋放這些引用。

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

而在你updateTimeLeft:只是重新安排計時器的方法,並設置一個條件下,應立即停止。

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

哦!我明白了,但實際上我仍然處於中間狀態,所以代碼是不正確的,我必須在完成一個關卡之後恢復它,並且一個關卡有20個問題。完成一個級別後,我必須展示廣告。所以這樣我必須重新啓動它。 非常感謝 –