1

After trying many ways to call a function in new thread only the below code worked for me

[NSThread detacNewThreadSelector:@selector(temp:) toTarget:self withObject:self];

The below didn't work:

NSThread *updateThread1 = [[NSThread alloc] initWithTarget:self selector:@selector(temp:) object:self];
NSThread *updateThread1 = [[NSThread alloc] init];
  [self performSelector:@selector(temp:) onThread:updateThread1 withObject:self waitUntilDone:YES];

Now when i try to call NSTimer or perform selector in timer: function it does not works Find below the code

int timeOutflag1 = 0;
-(void)connectCheckTimeOut
{
    NSLog(@"timeout");
    timeOutflag1 = 1;
}

-(void)temp:(id)selfptr
{
    //[selfptr connectCheckTimeOut];
    NSLog(@"temp");
    //[NSTimer scheduledTimerWithTimeInterval:5 target:selfptr selector:@selector(connectCheckTimeOut) userInfo:nil repeats:NO];
    [selfptr performSelector:@selector(connectCheckTimeOut) withObject:nil afterDelay:5];

}

- (IBAction)onUart:(id)sender {

    protocolDemo1 *prtDemo = [[protocolDemo1 alloc] init];

   //NSThread *updateThread1 = [[NSThread alloc] initWithTarget:self selector:@selector(temp:) object:self];
    //[self performSelector:@selector(temp:) onThread:updateThread1 withObject:self waitUntilDone:YES];
      // [updateThread1 start];
    [self performSelector:@selector(temp:) withObject:self afterDelay:0];

   while(1)
    {
        NSLog(@"Whieloop");
        if(timeOutflag1)
        {
            timeOutflag1 = 0;
            break;
        }
        if([prtDemo isConnected])
            break;

    }
}

If i use [self performSelector:@selector(connectCheckTimeOut) withObject:nil afterDelay:5]; in onUart function then it works properly i can see Timeout printf but inside temp it does not work.

Arun
  • 3,406
  • 4
  • 30
  • 55
ebdo
  • 157
  • 3
  • 14

1 Answers1

1

NSTimer is run-loop based, so if you want to use one on a background thread that you're spawning and managing yourself, you will need to start a runloop on that thread. Read up on NSRunLoop. The short version might look something like:

- (void)timedMethod
{
    NSLog(@"Timer fired!");
}

- (void)threadMain
{
    NSRunLoop* rl = [NSRunLoop currentRunLoop];
    NSTimer* t = [NSTimer scheduledTimerWithTimeInterval: 1.0 target: self selector: @selector(timedMethod) userInfo:nil repeats:YES];
    [rl run];
}

- (void)spawnThread
{
    [NSThread detachNewThreadSelector: @selector(threadMain) toTarget:self withObject:nil];
}
ipmcc
  • 29,581
  • 5
  • 84
  • 147
  • even the below code didn work -(void)temp:(id)selfptr { //[selfptr connectCheckTimeOut]; NSLog(@"temp"); NSRunLoop* rl = [[NSRunLoop alloc] init]; [NSTimer scheduledTimerWithTimeInterval:5 target:selfptr selector:@selector(connectCheckTimeOut) userInfo:nil repeats:NO]; // [selfptr performSelector:@selector(connectCheckTimeOut) withObject:nil afterDelay:5]; [rl run]; } – ebdo Sep 16 '13 at 12:11
  • hey its ok it worked with NSRunLoop *rl = [NSRunLoop currentRunLoop]; [NSTimer scheduledTimerWithTimeInterval:5 target:selfptr selector:@selector(connectCheckTimeOut) userInfo:nil repeats:NO]; // [selfptr performSelector:@selector(connectCheckTimeOut) withObject:nil afterDelay:5]; [rl run]; } However i would be happy if anyone can explain y it didn work with NSRunLoop* rl = [[NSRunLoop alloc] init]; but worked with NSRunLoop* rl = [NSRunLoop currentRunLoop]; – ebdo Sep 16 '13 at 12:18
  • Ah yes. It's been a while since I had created a run loop with this API. You can't alloc/init NSRunLoops. You call `currentRunLoop` and it creates one for you if necessary. From the docs: "If a run loop does not yet exist for the thread, one is created and returned" I'm guessing this is because they're a one-per-thread sort of thing. I edited the code in my answer to suit. – ipmcc Sep 16 '13 at 13:12
  • FWIW, I agree with other commenters that spawning a thread seems like a poor approach compared to using GCD, but hopefully this is helpful anyway. – ipmcc Sep 16 '13 at 13:16