views:

750

answers:

2

I am trying to run a timer in the background of my application, i am using the timer heavily in my application and i'd rather running it in the background, However i am getting memory leaks when trying to release the NSAoutreleasePool. My Timer class is singleton, so if i start new timer the old timer get dealloc it .

+ (void)timerThread{

    timerThread = [[NSThread alloc] initWithTarget:self selector:@selector(startTimerThread) object:nil]; //Create a new thread
    [timerThread start]; //start the thread
}

//the thread starts by sending this message
+ (void) startTimerThread
{
    timerNSPool = [[NSAutoreleasePool alloc] init];
    NSRunLoop* runLoop = [NSRunLoop currentRunLoop];
    timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(startTime:) userInfo:nil repeats:YES];
    //timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(startTime:) userInfo:nil repeats:YES];
    //[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
    [runLoop run];
    [timerNSPool release];
}

+ (void)startTime:(NSTimer *)theTimer{

    if(timeDuration > 1)
        timeLabel.text = [NSString stringWithFormat:@"%d",--timeDuration];
    else{
        [self stopTimer];
        [delegate timeIsUp];
    }

}
+ (void) stopTimer{

    if(timer != nil)
    {       
        [timerThread release]; 
        [timeLabel release];
        [timer invalidate];
        timer = nil;
    }

}

I never had a problem running the NSTimer on the main thread runLoop with application autoreleasepool. I am getting leak at [timerNSPool release]; GeneralBlock-16 Malloc WebCore WKSetCurrentGraphicsContext

What causing the Leak is updating UI from a secondary thread :

timeLabel.text = [NSString stringWithFormat:@"%d",--timeDuration];

However i added another method updateTextLbl, then i am calling it using this

[self performSelectorOnMainThread:@selector(updateTextLbl) withObject:nil waitUntilDone:YES];

on the main thread. I did not have leaks at all , but this will defeats the purpose of having a second threads.

This my first post , and i appreciate any help Thanks... in advance....

A: 

Off the cuff, the NSRunLoop you have in there seems a bit out of place. From the docs:

In general, your application does not need to either create or explicitly manage NSRunLoop objects. Each NSThread object, including the application’s main thread, has an NSRunLoop object automatically created for it as needed. If you need to access the current thread’s run loop, you do so with the class method currentRunLoop.

You have a timer, starting a thread, that gets the current run loop and tries to start running it. Do you want to associate the timer with that run loop?

Via a call to:

(void)addTimer:(NSTimer *)aTimer forMode:(NSString *)mode

?

David Sowsy
I am not creating any NSRunLoop i am just getting a reference to the current loop which is the current thread run loop.
Unis
+2  A: 

You're updating your UI in +startTime:, but that method does not run in the main thread. That may be the source of the WebCore warning you're seeing.

Darren
Actually this might be the case, Thanks. Any idea how can i try to update my UI from a secondary threads without running to this memory leaks?
Unis
Use -performSelectorOnMainThread:withObject:waitUntilDone:. However, if that's all your Timer does then there's no point running it in its own thread.
Darren
The only reason i would like to have the timer running on it's own thread because i use it constantly for every player turn, so it's being used throughout the application run time, also i've noticed performance issue when interacting with the UI while running the timer on the main thread, that's why i moved to a second thread, any advise are welcomed...
Unis