0

I want fire a NSTimer to do something period in a C function. e.g.

void test()
{
    PJsipServices *sipServices = [PJsipServices sharePjsipServices];
    sipServices->_signalLevelSampleTimer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:sipServices selector:@selector(readSignalLevel:) userInfo:nil repeats:YES];
}

but this code doesn't work... if anyone has guides such as C programming with Objective-C, please give me some information.

starcwl
  • 396
  • 2
  • 9

3 Answers3

1

NSTimer should only be called from a thread which contains NSRunloop. Usually this is the Main Thread but if you do not want to block the Main Thread then another option would be to schedule the timer using GCD Queues!

Asif Mujteba
  • 4,596
  • 2
  • 22
  • 38
0

I would implement a C function in an Objective-C file, and use Objective-C in the implementation.

Simply put, make the implementation a .m file, but don't expose any Objective-C in its header.

The darker more perilous road is to use the C functions in #import <objc/objc.h> and #import <objc/objc-runtime.h> to invoke methods. But only do so very carefully. The fact that you had to ask this question suggests you shouldn't venture into that territory without lots of reading, thinking, and tinkering with the Objective-C runtime.

Fabian
  • 6,973
  • 2
  • 26
  • 27
0

You can't use NSTimer unless you have a run loop.

So, instead use GCD which is better anyway:

static void dispatch_repeated_internal(dispatch_time_t firstPopTime, double intervalInSeconds, dispatch_queue_t queue, void(^work)(BOOL *stop))
{
  __block BOOL shouldStop = NO;
  dispatch_time_t nextPopTime = dispatch_time(firstPopTime, (int64_t)(intervalInSeconds * NSEC_PER_SEC));
  dispatch_after(nextPopTime, queue, ^{
    work(&shouldStop);
    if(!shouldStop)
    {
      dispatch_repeated_internal(nextPopTime, intervalInSeconds, queue, work);
    }
  });
}

void dispatch_repeated(double intervalInSeconds, dispatch_queue_t queue, void(^work)(BOOL *stop))
{
  dispatch_time_t firstPopTime = dispatch_time(DISPATCH_TIME_NOW, intervalInSeconds * NSEC_PER_SEC);
  dispatch_repeated_internal(firstPopTime, intervalInSeconds, queue, work);
}

void test()
{
    PJsipServices *sipServices = [PJsipServices sharePjsipServices];

    dispatch_repeated(0.1, dispatch_get_main_queue(), ^(BOOL *stop) {
        [sipServices readSignalLevel:nil];

        // you might wanna set stop to YES to abort now
    });
}

(Thanks to: https://stackoverflow.com/a/14582980/19851https://stackoverflow.com/a/14582980/19851)

Community
  • 1
  • 1
Abhi Beckert
  • 32,787
  • 12
  • 83
  • 110