Timer-related delay calls in iOS, common in NSObject PerformSelector:withObject:afterDelay: This method sets the timer in the current runloop when it is called, There is also a delay to configure the task directly using Nstimer .
Both of these methods have a common premise, that is, the current thread needs to have a running runloop and the Runloop has a timer inside.
We know: Only the main thread will be created by default automatically run a runloop, and have a timer, normal child threads are not these. This brings up a problem, sometimes we are not sure whether our module will be called asynchronously, and we write such a delay call is generally not to check the runtime environment, so that in the child thread is called, our code in the delay call code will wait for the timer to dispatch, But actually there is no such timer in the child thread, so our code will never be transferred.
The following code shows the differences between the performselector and the Dispatch_time
- /*
- Add to queue with GCD delay
- */
- -(void) testdispatch_after{
- dispatch_time_t time = Dispatch_time (Dispatch_time_now, 3*nsec_per_sec);
- dispatch_queue_t queue = Dispatch_get_global_queue (Dispatch_queue_priority_default, 0);
- Dispatch_after (time, queue, ^{
- NSLog (@ "added to queue after 3 seconds");
- });
- Dispatch_release (queue);
- }
- -(void) testdelay{
- NSLog (@ "Testdelay is executed");
- }
- /*
- The role of the Dispatch_barrier_async fence
- */
- -(void) testdispatch_barrier{
- //dispatch_queue_t gcd = Dispatch_queue_create ("This is a sequence queue", NULL);
- dispatch_queue_t gcd = dispatch_queue_create ("This is a concurrent queue", dispatch_queue_concurrent);
- Dispatch_async (GCD, ^{
- NSLog (@ "B0");
- //This selector will not execute because there is no runloop in the thread
- [self performselector:@selector (testdelay) withobject: nil Afterdelay:3];
- //code will execute because the GCD method is used
- [self testdispatch_after];
- });
- Dispatch_release (GCD);
- }
In a multi-threaded environment, such performselector delay calls are in fact a lack of security . We can solve this problem with another set of solutions, that is, using the dispatch_after in GCD to achieve a single time delay call
There is also a solution:
Performselector is not without the means to ensure thread safety. For example, the following code can be run:
- [self performselector:@selector (testdelay) onthread:[nsthread Mainthread] withobject: Nil Waituntildone:NO];
The selector is specified to run in the main thread.
There is also a solution:
- [self performselector:@selector (testdelay) withobject: nil afterdelay:3 inmodes:[ Nsarray Arraywithobject:nsdefaultrunloopmode]];
- [[Nsrunloop Currentrunloop] runmode:nsdefaultrunloopmode beforedate:[nsdate Distantfuture]];
Start the thread in Runloop, because each thread has a default Runloop
IOS Nsrunloop those things