GCD is a pure C language, but it is also soluble in object-oriented thinking, based on block.
1, GCD Advantages:
- Ease of use: GCD is easier to use than thread, and the block-based feature makes it extremely simple to pass the context between different code scopes.
- Efficiency: GCD is more practical and fast in many places than it is dedicated to creating threads that consume resources.
- Performance: GCD automatically increases and decreases the number of threads based on system load, reducing context switching and increasing computational efficiency.
2, the use of GCD
2.1.dispatch Async Async Operation
2.1.1. Define the Action (Task) you want to perform, append to the appropriate queue (Dispatch queue)
2.12.Queue Type:
(1) Serial Dispatch queue-Wait for the task that is currently being executed to finish (serial)
(2) Concurrent Dispatch queue-does not wait for the end of the task being performed (parallel, concurrency)
2.1.3. Define the queue yourself and add the task to the custom queue
(1) Create a queue
//第一个参数:给队列起名字//第二个参数:queue的类型 (默认是串行的) dispatch_queue_t queue1 = dispatch_queue_create("com.wxhl.gcd.Queue1"NULL); dispatch_queue_t queue2 = dispatch_queue_create("com.wxhl.gcd.Queue2", DISPATCH_QUEUE_CONCURRENT); //并行的queue
(2) Create a task to perform, add to the queue
dispatch_async(queue2, ^{ for (int050; i ++) { NSLog(@"GCD : %d", i); } });
2.1.4. Using the system to provide a queue ( recommended )
Two kinds of
Main Dispatch queue Global Dispatch queue
Serial (main thread) parallelism
//main dispatch_queue_tMainqueue = Dispatch_get_main_queue ();Dispatch_async(Mainqueue, ^{; });//global //Parameter one: Priority //Parameter two: identifiers dispatch_queue_tGlobalqueue = Dispatch_get_global_queue (Dispatch_queue_priority_default,0);Dispatch_async(Globalqueue, ^{//Request network data //Display on UI interface Dispatch_async(Dispatch_get_main_queue (), ^{//ui Related Codes}); });//Main thread for(inti =0; I < -; i + +) {NSLog(@"Main thread:%d", i); }
//async: asynchronous 将任务异步的追加到队列中 dispatch_async(dispatch_get_global_queue(0, 0), ^{ NSLog(@"async"); });
2.2 Dispatch Sync sync operation
//sync:synchronous Append task synchronization to the queue (the tasks in the queue are finished, and the task is appended to the queue) //Is synchronous append, not task synchronous execution, in serial queue, task is executed synchronously Dispatch_sync(Dispatch_get_global_queue (0,0), ^{NSLog(@"Sync"); }); **Dispatch_syncProblem: Easy to generate deadlock * * Example1:Dispatch_sync(Dispatch_get_main_queue (), ^{NSLog(@"Hello"); });NSLog(@"Main thread");//The code above executes the specified block in the main queue, waiting for its execution to end //And the main queue is already executing the above code, unable to execute the additional blockExample2://serial queue dispatch_queue_tQueue = Dispatch_queue_create ("Com.wxhl.GCD.queue",NULL);Dispatch_async(Queue, ^{Dispatch_sync(Queue, ^{NSLog(@"Serial queue"); }); });
3. GCD Advanced Usage
3.1 Dispatch after
After some time, append the task you want to perform to the queue
- (void) Viewdidload {[SuperViewdidload];//Creation time //Relative time point relative to the first parameter after how longdispatch_time_t time = Dispatch_time (Dispatch_time_now,3ull * nsec_per_sec);//unit of Time //nsec_per_sec sec //nsec_per_msec Ms //nsec_per_usec μs //dispatch_time_t The specified timeDispatch_after (Time, Dispatch_get_main_queue (), ^{NSLog(@"after 3s"); });//Second usageDispatch_after_f (Dispatch_time (Dispatch_time_now,3ull * nsec_per_sec), Dispatch_get_main_queue (),NULL, func1);//Use your ownDispatch_after (Dispatch_time (Dispatch_time_now, (int64_t) (5ull * nsec_per_sec)), Dispatch_get_main_queue (), ^{; });#warning Note //1. Do the task after a period of time (instead of appending the task you want to perform to the queue) //2. Main thread runloop 1/60 sec Detection Event, additional time range 3s-(3 + 1/60) s}voidFunc1 () {}@end
3.2 Dispatch Group
Dispatch_group_async: Using the group to monitor the execution of a queue task
Dispatch_group_notify: All Tasks Execute end rollup, do not block current thread
Dispatch_group_wait: Wait until all tasks are executed and cannot be canceled halfway, blocking the current thread
- (void) Viewdidload {[SuperViewdidload];//1. Creating a groupdispatch_group_t group = Dispatch_group_create ();//2. Getting Queues dispatch_queue_tQueue = Dispatch_get_global_queue (0,0);//3. Using the group to monitor the execution of a queue taskDispatch_group_async (group, queue, ^{NSLog(@"Task 1"); }); Dispatch_group_async (group, queue, ^{NSLog(@"Task 2"); }); Dispatch_group_async (group, queue, ^{NSLog(@"Task 3"); }); Dispatch_group_async (group, queue, ^{sleep (6);NSLog(@"Task 4"); });//(1) Monitored functions //Monitor to the end of the task execution in the queue, execute the task inside the blockDispatch_group_notify (group, queue, ^{//End processing NSLog(@"Done"); });//(2) //Wait for time, based on the return value of the wait function, to determine whether the task in the queue is finished, and summarize the results after 5 seconds, regardless of whether the task has finished executingdispatch_time_t time = Dispatch_time (Dispatch_time_now,5* nsec_per_sec);//dispatch_group_wait After the specified time, see if the queue task is complete //If done, return 0 //If not finished, returns a value other than 0 Longresult = Dispatch_group_wait (group, time);if(Result = =0) {NSLog(@"Finish"); }Else{NSLog(@"Not Finish"); }//dispatch_group_wait will block the current thread and will not return until the specified time has been called for this functionSleep2);NSLog(@"Main");}@end
3.3 Dispatch once realization of a single case
Viewcontroller.m
- (void)viewDidLoad { [super viewDidLoad]; //dispatch once //保证block里的任务只执行一次 staticdispatch_once_t onceToken; dispatch_once(&onceToken, ^{ NSLog(@"只会执行一次"); }); }@end
Addressbook.m
#import "AddressBook.h" StaticAddressBook *instance =Nil; @implementation addressbook /* * Single-case singleton mode try not to use * 1. Meaning: A class creates only one object * 2. Lifecycle: Starting from creation, the application exits the end * 3. The method of obtaining a singleton object, naming the rule: share default * 4. Memory management as far as possible by this class to manage */< /c3>+ (AddressBook *) sharedinstance{//oncetoken Tag whether the code in block has been executed Static dispatch_once_tOncetoken;dispatch_once(&oncetoken, ^{instance = [[AddressBook alloc] init]; });returninstance;}//alloc will automatically call Allocwithzone://zone Space Allocation memory space (zone), creating objects+ (ID) Allocwithzone: (Nszone *) zone{if(Instance = =Nil) {instance = [SuperAllocwithzone:zone]; }returninstance;}@end
4. Summary:
- Security: No locking or other synchronization mechanisms are required.
- Take advantage of multi-core
- All multithreaded code is centralized for easy maintenance
- No practical @autoreleasepool in GCD
- If you want to execute sequentially, you can use the Dispatch_sync synchronization method (Dispatch_sync cannot determine the order in which the tasks are executed)
- When calling the main thread queue task to update the UI, it is best to use the synchronization method
Multi-thread gcd (Grand central Dispatch)