Question

I am trying to run a NSTimer on a thread using iPhone SDK 3.0. I think I am doing everything correctly (new runloop etc.). If I call [timer invalidate] on viewDidDissappear though I get this error:

bool _WebTryThreadLock(bool), 0x3986d60: Tried to obtain the web lock from a thread other than the main thread or the web thread. This may be a result of calling to UIKit from a secondary thread. Crashing now... Program received signal: “EXC_BAD_ACCESS”.

Here is my code:

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    [activityIndicator startAnimating];
    NSThread* timerThread = [[NSThread alloc] initWithTarget:self selector:@selector(timerStart) object:nil]; //Create a new thread
    [timerThread start]; //start the thread
}

-(void)timerStart
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    NSRunLoop* runLoop = [NSRunLoop currentRunLoop];
    //Fire timer every second to updated countdown and date/time
    timer = [[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(method) userInfo:nil repeats:YES] retain];
    [runLoop run];
    [pool release];
}

- (void)viewDidDisappear:(BOOL)animated {
    [super viewDidDisappear:animated];
    [timer invalidate];
}

When I remove the line invalidating the timer everything works fine. Am I not supposed to invalidate it or am I making some other mistake?

Thanks

Was it helpful?

Solution

Try

[timer performSelector:@selector(invalidate) onThread:timerThread withObject:nil waitUntilDone:NO];

instead. You will have to make timerThread an ivar of your view controller.

OTHER TIPS

    - (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    NSThread* timerThread = [[NSThread alloc] initWithTarget:self selector:@selector(timerStart) userInfo:nil repeats:TRUE];
    [timerThread start]; 
    }

    -(void)timerStart
    {
   @autoreleasePool{
    NSRunLoop *TimerRunLoop = [NSRunLoop currentRunLoop];
    [NSTimer scheduleTimerWithInterval:0.1 target:self selector:@selector(methodName:) userInfo:nil repeat:YES];
    [TimerRunLoop run];
    }

    - (void)viewDidDisappear:(BOOL)animated {
    [super viewDidDisappear:animated];
    }

I guess you have done some UI work in "method".

 timer = [[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(method) userInfo:nil repeats:YES] retain];

From the log, it seems you have done UI updating work it in "Timer" thread in "method".

you can use block to dispatch work on main thread or performSeletorOnMainThread for doing "method"

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top