在Objective - C中的另一个线程中的计时器

时间:2021-11-25 20:59:48

I have to define method which should be invoked periodically with some time interval. I need to invoke it in another thread (NOT main thread), because this method is used to get information from external API and sync data in core data.

我必须定义应该以一定的时间间隔定期调用的方法。我需要在另一个线程(非主线程)中调用它,因为此方法用于从外部API获取信息并在核心数据中同步数据。

How do I define this method to not block main thread?

如何定义此方法以不阻止主线程?

2 个解决方案

#1


13  

Unless you have a specific need for timers, you can use Grand Central Dispatch.

除非您特别需要计时器,否则您可以使用Grand Central Dispatch。

The following snippet will execute a block after 2 seconds, on the default priority concurrent queue (i.e a background thread). You can change the priority of the queue if you see fit, but unless you're dealing with lots of different operations on concurrent queues, default will suffice.

以下代码段将在默认优先级并发队列(即后台线程)上2秒后执行一个块。如果您认为合适,可以更改队列的优先级,但除非您在并发队列上处理大量不同的操作,否则默认就足够了。

double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));

dispatch_after(popTime, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
    // Your code here
});

If you're wanting to call this repeatedly, then you can use dispatch_source_set_timer to set a recurring execution. The jist of it is below:

如果您想重复调用它,则可以使用dispatch_source_set_timer设置重复执行。它的主旨如下:

// Create a dispatch source that'll act as a timer on the concurrent queue
// You'll need to store this somewhere so you can suspend and remove it later on
dispatch_source_t dispatchSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0,
                                                          dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)); 

// Setup params for creation of a recurring timer
double interval = 2.0;
dispatch_time_t startTime = dispatch_time(DISPATCH_TIME_NOW, 0);
uint64_t intervalTime = (int64_t)(interval * NSEC_PER_SEC);
dispatch_source_set_timer(dispatchSource, startTime, intervalTime, 0);

// Attach the block you want to run on the timer fire
dispatch_source_set_event_handler(dispatchSource, ^{
    // Your code here
});

// Start the timer
dispatch_resume(dispatchSource);

// ----

// When you want to stop the timer, you need to suspend the source
dispatch_suspend(dispatchSource);

// If on iOS5 and/or using MRC, you'll need to release the source too
dispatch_release(dispatchSource);

#2


1  

Use NSRunLoop and NSTimer for work

使用NSRunLoop和NSTimer进行工作

NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timer) userInfo:nil repeats:NO];

[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];

#1


13  

Unless you have a specific need for timers, you can use Grand Central Dispatch.

除非您特别需要计时器,否则您可以使用Grand Central Dispatch。

The following snippet will execute a block after 2 seconds, on the default priority concurrent queue (i.e a background thread). You can change the priority of the queue if you see fit, but unless you're dealing with lots of different operations on concurrent queues, default will suffice.

以下代码段将在默认优先级并发队列(即后台线程)上2秒后执行一个块。如果您认为合适,可以更改队列的优先级,但除非您在并发队列上处理大量不同的操作,否则默认就足够了。

double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));

dispatch_after(popTime, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
    // Your code here
});

If you're wanting to call this repeatedly, then you can use dispatch_source_set_timer to set a recurring execution. The jist of it is below:

如果您想重复调用它,则可以使用dispatch_source_set_timer设置重复执行。它的主旨如下:

// Create a dispatch source that'll act as a timer on the concurrent queue
// You'll need to store this somewhere so you can suspend and remove it later on
dispatch_source_t dispatchSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0,
                                                          dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)); 

// Setup params for creation of a recurring timer
double interval = 2.0;
dispatch_time_t startTime = dispatch_time(DISPATCH_TIME_NOW, 0);
uint64_t intervalTime = (int64_t)(interval * NSEC_PER_SEC);
dispatch_source_set_timer(dispatchSource, startTime, intervalTime, 0);

// Attach the block you want to run on the timer fire
dispatch_source_set_event_handler(dispatchSource, ^{
    // Your code here
});

// Start the timer
dispatch_resume(dispatchSource);

// ----

// When you want to stop the timer, you need to suspend the source
dispatch_suspend(dispatchSource);

// If on iOS5 and/or using MRC, you'll need to release the source too
dispatch_release(dispatchSource);

#2


1  

Use NSRunLoop and NSTimer for work

使用NSRunLoop和NSTimer进行工作

NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timer) userInfo:nil repeats:NO];

[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];