в NSTimer растет утечка - PullRequest
0 голосов
/ 09 ноября 2011

Я использую подкласс в своем приложении, в котором я использую 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];


}

Я сохранил этот таймер. Если не сохранить, то сбой приложения.

Пожалуйста, подскажите, как устранить эту утечку

Шивы

Ответы [ 2 ]

0 голосов
/ 09 ноября 2011

Что происходит, вы вызываете метод resetIdleTimer каждый раз, когда пользователь нажимает на экран. Это увеличивает счет сохранения idleTimer каждый раз, потому что вы сохранили его. Причина сбоя вашего приложения, если вы не сохраняете его, заключается в том, что вы получаете автоматически освобожденный объект NSTimer из метода класса NSTimer

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

Это означает, что вы не можете использовать этот объект вне этого конкретного метода, как вы используете в методе resetApplication. Теперь вы можете проверять счетчик каждый раз, когда сохраняете его, но это хлопотно. Поэтому я предлагаю объявить idleTimer как свойство сохранения.

@property (retain) NSTimer *idleTimer;

и синтезировать его сеттеры и геттеры после реализации.

@synthesize idleTimer;

теперь используйте

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

и освобождайте idleTimer только в вашей ячейке.

0 голосов
/ 09 ноября 2011

Использовать назначенное свойство для переменной таймера.ех.

NSTimer globalTimer;

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

Теперь назначьте таймер для этой переменной и используйте как self.globalTimer.Во-первых, всегда назначайте nil для переменной после использования.Не выпускайте его другим способом, так как это приведет к падению вашего приложения.

...