2011-11-09 41 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