1

I have some web service data in my app that needs to be updated every 3 minutes. I had tried out a few approaches but got a really good piece of advise in here last week, I should not build a new thread every 3 minutes and then subsequently try and dealloc and synchronize all the different parts so that I avoided memory bug. Instead I should have a "worker thread" that was always running, but only did actual work when I asked it too (every 3 minutes).

As my small POC works now, I spawn a new thread in the applicationDidFinishLaunching method. I do this like so:

[NSThread detachNewThreadSelector:@selector(updateModel) toTarget:self withObject:nil];

- (void) updateModel {

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    BackgroundUpdate *update = [[BackgroundUpdate alloc] initWithTimerInterval:180];
    [update release];
    [pool release];
}

Ok, this inits the "BackgroundUpdate" object with the update interval in seconds. Inside the updater it is simply like this for now:

@implementation BackgroundUpdate

- (id) initWithTimerInterval:(NSInteger) secondsBetweenUpdates {

    if(self = [super init]) {

        [NSTimer scheduledTimerWithTimeInterval:secondsBetweenUpdates 
                                        target:self 
                                        selector:@selector(testIfUpdateNeeded) 
                                        userInfo:nil 
                                        repeats:YES];
    }

    return self;
}

- (void) testIfUpdateNeeded {

    NSLog(@"Im contemplating an update...");

}

I have never used threads like this before. I has always been "setup autoReleasePool, do work, get your autoReleasePool drained, and goodbye".

My problem is that as soon as the initWithTimerInterval has run, the NSThread is done, it therefore returns to the updateModel method and has its pool drained. I guess it has to do with the NSTimer having it's own thread/runloop? I would like for the thread to keep having the testIfUpdateNeeded method run every 3 minutes.

So how will I keep this NSThread alive for the entire duration of my app?

Thank You for any help/advice given:)

RickiG
  • 11,380
  • 13
  • 81
  • 120

2 Answers2

5

You're close. All you need to do now is start the run loop running so the thread doesn't exit and the timer runs. After your call to initWithTimerInterval:, just call

[[NSRunLoop currentRunLoop] run];

The thread will run its run loop indefinitely and your timer will work.

Ken Aspeslagh
  • 11,484
  • 2
  • 36
  • 42
  • Thank You Ken, exactly:) It now ticks along and when the timer fires I get my model updated:) – RickiG Feb 23 '10 at 22:14
0

It sounds like you might want an NSOperation instead of an old fashion thread. You could active the operation via a universal timer then it would execute on its own thread and then clean up its own memory when done.

TechZen
  • 64,370
  • 15
  • 118
  • 145
  • Thanks TechZen. I read parts of the guide you linked to and learned something new:) They however don't recommend NSOperation for repetitive tasks, but rather for queuing an arbitrary set of tasks that has dependencies. Why it is not just the "Thread in a box" solution, however, I cant say. It did sound very promising at first:) – RickiG Feb 23 '10 at 22:18
  • Okay, I missed that. Good to know. – TechZen Feb 24 '10 at 12:07