2011-11-09 60 views
0

我在我的應用程序中使用了一個子類,其中我使用nstimer來檢測用戶空閒/非活動狀態。 這是一個泄漏,它在每個水龍頭上都會產生。 這裏是我的類泄漏在NSTimer中上升

- (void)sendEvent:(UIEvent *)event { 
    [super sendEvent:event]; 
    isRootView=FALSE; 
    // Only want to reset the timer on a Began touch or an Ended touch, to reduce the number of timer resets. 
    NSSet *allTouches = [event allTouches]; 
    if ([allTouches count] > 0) { 
     // allTouches count only ever seems to be 1, so anyObject works here. 
     UITouchPhase phase = ((UITouch *)[allTouches anyObject]).phase; 
     if (phase == UITouchPhaseBegan) 
      [self resetIdleTimer]; 
    } 

} 

- (void)resetIdleTimer { 

    if (idleTimer) 
    { 
     if ([idleTimer isValid]) 
     { 
      [idleTimer invalidate]; 
      //[idleTimer release]; 
      //idleTimer=nil; 
     } 
    } 
    maxIdleTime = 60; 
    if (!isRootView) 
    { 
     idleTimer = [NSTimer scheduledTimerWithTimeInterval:maxIdleTime target:self selector:@selector(idleTimerExceeded) userInfo:nil repeats:NO]; 
     [idleTimer retain]; 
    } 
    else { 
     if ([idleTimer isValid]) 
     { 
      [idleTimer invalidate]; 
      //[idleTimer release]; 
      //idleTimer = nil; 
     } 
     if ([resetTimer isValid]) { 
      [resetTimer invalidate]; 
      resetTimer=nil; 

     } 
    } 


} 

- (void)idleTimerExceeded { 

    alert=[[UIAlertView alloc] initWithTitle:@"Confirmation!" message:@"Would you like to continue placing the order ?" delegate:self cancelButtonTitle:@"NO" otherButtonTitles:@"YES", nil]; 
    alert.tag=100; 
    [alert show]; 
    [alert release]; 
    resetTimer=[NSTimer scheduledTimerWithTimeInterval:maxIdleTime target:self selector:@selector(resetApplication) userInfo:nil repeats:NO] ; 
} 
-(void) alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{ 
    if (alertView.tag==100) { 
     if (buttonIndex==1) 
     { 
      if ([resetTimer isValid]) { 
       [resetTimer invalidate]; 
       resetTimer=nil; 

      } 
     } 
     else { 
      [self resetApplication]; 
     } 
    } 
} 
-(void) resetApplication 
{ 
    isRootView=TRUE; 
    [alert dismissWithClickedButtonIndex:1 animated:YES]; 
    if ([resetTimer isValid]) 
    { 
     [resetTimer invalidate]; 
     resetTimer=nil; 
    } 

    if (idleTimer) 
    { 
     [idleTimer invalidate]; 
     [idleTimer release]; 
     idleTimer = nil; 
    } 

    SushiTeriaAppDelegate *appDelegate=(SushiTeriaAppDelegate*)[[UIApplication sharedApplication] delegate]; 
    [appDelegate resetApp]; 

} 


- (void)dealloc { 
    [super dealloc]; 

    //[resetTimer release]; 

    [alert release]; 


} 

我保留這個計時器的代碼。如果不保留,則應用程序崩潰。

請指導我如何消除這種泄漏

shivam

回答

0

使用分配屬性定時器變量。 ex。

NSTimer globalTimer; 

@property (nonatomic, assigned) NSTimer globalTimer; 
@synthesize globalTimer; 

現在在這個變量上分配定時器,並使用像self.globalTimer。 有一點是總是在使用後將變量賦給nil。不要釋放它另一個明智的將 墜毀您的應用程序。

+0

它崩潰應用程序 –

+0

如果([idleTimer isValid])在這一行 –

+0

它崩潰應用程序,當我嘗試使無效計時器 –

0

發生的是,每當用戶點擊屏幕時,都會調用resetIdleTimer方法。這會每次增加空閒計時器的保留計數,因爲您保留了它。您的應用程序崩潰,如果你不保留的原因是因爲你得到的NSTimer類方法的自動釋放的NSTimer對象

idleTimer=[NSTimer scheduledTimerWithTimeInterval:maxIdleTime target:self selector:@selector(idleTimerExceeded) userInfo:nil repeats:NO]; 

這意味着,當你在resetApplication方法做,你不能使用這個對象的特定方法之外。現在,您可以在每次保留它時檢查保留計數,但這很麻煩。所以我建議你將idleTimer聲明爲保留屬性。

@property (retain) NSTimer *idleTimer; 

和實施後合成的getter和setter方法。

@synthesize idleTimer; 

現在使用

self.idleTimer=[NSTimer scheduledTimerWithTimeInterval:maxIdleTime target:self selector:@selector(idleTimerExceeded) userInfo:nil repeats:NO]; 

,只有在你的dealloc釋放idleTimer。

+0

但是這是一個子類,所以dealloc不會被調用, 我是對嗎? –

+0

的子類是什麼?我無法得到你。無論您的對象是否被釋放或不在實際使用中都沒有關係。無論哪種方式,使用nstimer的屬性將解決您遇到的任何內存泄漏。 – MadhavanRP