IOS multithreading and ios Multithreading
1. Communication between threads
// There is a particularly time-consuming operation, such as a network request, to enable the Sub-thread to request the network, we generally want to update the UI in the main thread, how to jump from the sub-thread to the main thread?
# Import "ViewController. h"
@ Interface ViewController ()
@ Property (weak, nonatomic) IBOutlet UIImageView * imageView;
@ End
@ Implementation ViewController
-(IBAction) downLoadImage :( id) sender {
[Self defined mselectorinbackground: @ selector (loadImage) withObject: nil];
}
-(Void) loadImage {
NSLog (@ "loadImage-% @", [NSThread currentThread]);
NSString * urlString = @ "http://design.yesky.com/uploadImages/2009/335/20091201140951681.jpg ";
NSData * data = [NSData dataWithContentsOfURL: [NSURL URLWithString: urlString];
UIImage * image = [UIImage imageWithData: data];
// WaitUntilDone
// [Self defined mselecw.mainthread: @ selector (changeMainThread :) withObject: image waitUntilDone: NO];
// [Self defined mselector: @ selector (changeMainThread :) onThread: [NSThread mainThread] withObject: image waitUntilDone: YES];
[Self. imageView extends mselector: @ selector (setImage :) onThread: [NSThread mainThread] withObject: image waitUntilDone: NO];
// WaitUntilDone: What does it mean?
// YES: wait for loadImage: After this method is executed, execute subsequent operations of the current thread.
// NO: Do not wait for loadImage: After this method is executed, execute the subsequent operations of the current thread.
NSLog (@ "waitUntilDone ");
// Self. imageView. image = image;
}
2. GCD Basics
Core concepts
Task: operations to be performed in the block
Queue: adds a task to the queue and executes the task according to the first-in-first-out principle.
Serial queue: one-by-one execution
Parallel queue: Allows concurrent (concurrent) Execution of multiple tasks (automatically enabling multiple threads to execute tasks at the same time). The concurrent function is only valid under the asynchronous (dispatch_async) function.
Synchronization task: no new threads are opened. The task is executed in the current thread and the task is executed immediately.
Asynchronous tasks: New threads will be opened up (the main queue column is not allowed), and tasks will be executed in the newly opened threads (the main queue is executed in the main thread), rather than immediately executing the task
Synchronous task serial queue: New threads are not enabled and tasks are executed sequentially in the current thread.
Synchronization task parallel queue: New threads are not enabled, tasks are executed in the current thread, and tasks are executed immediately.
Asynchronous task serial queue: it opens up a new thread to execute the task in the new thread, instead of immediately executing
Asynchronous task parallel queue: New threads will be opened up and tasks will be executed in the newly opened threads. The task completion sequence is unordered rather than immediate execution.
Main queue column (Special serial Queue): The task is only scheduled in the main thread and no new threads are opened (usually used to refresh the UI)
Asynchronous task main queue: no new threads are opened, tasks are executed in the current thread, and tasks are not executed immediately.
Synchronization task queue: deadlock
Global Queue (parallel Queue): The global queue is shared with applications, and priority can be set.
New threads: determined by the task, the synchronization task will not open up new threads, and the asynchronous task will open up new threads (the main queue will not open up new threads)
Number of threads opened: determined by the queue, the serial queue only opens one thread, and the parallel queue opens up multiple threads. The number of threads is determined by the number of tasks and the bottom layer of GCD.
*/
-(Void) gcdTest6 {
Dispatch_queue_t queue = dispatch_get_main_queue ();
NSLog (@ "1 ");
// Execute the synchronization operation in the main queue to generate a deadlock
// Cause: the synchronization thread will execute the task only after the main thread ends. The main thread will execute the next task only after the synchronization is executed immediately.
Dispatch_sync (queue, ^ {
NSLog (@ "2 ");
});
NSLog (@ "3 ");
}
-(Void) gcdTest5 {
// The main queue column is a special serial queue.
// Features: it is specially responsible for scheduling tasks on the main thread and does not schedule tasks in sub-threads any more. For synchronous or asynchronous call tasks, they will only be executed on the main thread
Dispatch_queue_t queue = dispatch_get_main_queue ();
NSLog (@ "start ");
For (NSInteger I = 0; I <10; I ++ ){
// Asynchronous operations are performed on the main queue. There is a waiting process for asynchronous operations.
Dispatch_async (queue, ^ {
NSLog (@ "% @", [NSThread currentThread]);
});
}
NSLog (@ "end ");
}
// Concurrent queue: multiple threads run simultaneously
// Synchronous operation: no new thread is enabled
// Execution result: no new thread is enabled. Execute now
-(Void) gcdTest4 {
Dispatch_queue_t queue = dispatch_queue_create ("com. bjsxt", DISPATCH_QUEUE_CONCURRENT );
NSLog (@ "start ");
For (NSInteger I = 0; I <10; I ++ ){
Dispatch_sync (queue, ^ {
NSLog (@ "% @, % @", [NSThread currentThread], @ (I ));
});
}
NSLog (@ "end ");
}
// Concurrent queue: multiple threads run simultaneously
// Asynchronous Operation: A New thread is enabled.
// Execution result: a new thread is opened and the task is executed in the newly opened thread. The task completion sequence is unordered, rather than immediate execution.
-(Void) gcdTest3 {
// Enable concurrent queue
Dispatch_queue_t queue = dispatch_queue_create ("com. bjsxt", DISPATCH_QUEUE_CONCURRENT );
NSLog (@ "start ");
For (NSInteger I = 0; I <10; I ++ ){
// Perform asynchronous operations
Dispatch_async (queue, ^ {
NSLog (@ "% @", [NSThread currentThread]);
});
}
NSLog (@ "end ");
}
// Serial queue: one by one
// Asynchronous Operation: A New thread is enabled.
// Execution result: Start a new thread and execute the task in the new thread, instead of immediately executing
-(Void) gcdTest2 {
Dispatch_queue_t queue = dispatch_queue_create ("com. bjsxt", NULL );
NSLog (@ "start ");
For (NSInteger I = 0; I <10; I ++ ){
// Asynchronous request
Dispatch_async (queue, ^ {
NSLog (@ "% @, % @", [NSThread currentThread], @ (I ));
});
}
NSLog (@ "end ");
}
// Serial queue: one by one
// Synchronous operation: do not enable a new thread
// Execution result: New threads are not enabled and executed sequentially.
-(Void) gcdTest1 {
// Label: queue name
// Attr: queue attributes (serial, concurrent)
// DISPATCH_QUEUE_SERIAL serial
// DISPATCH_QUEUE_CONCURRENT concurrency
// # Define DISPATCH_QUEUE_SERIAL NULL
Dispatch_queue_t queue = dispatch_queue_create ("com. bjsxt", DISPATCH_QUEUE_SERIAL );
NSLog (@ "start ");
// Synchronous operation
// Operation task: block
Dispatch_sync (queue, ^ {
// Print the current thread
NSLog (@ "% @", [NSThread currentThread]);
});
NSLog (@ "end ");
}
3. Communication between GCD threads
# Import "ViewController. h"
@ Interface ViewController ()
@ Property (weak, nonatomic) IBOutlet UIImageView * imageView;
@ End
@ Implementation ViewController
-(IBAction) downLoadImage :( id) sender {
NSLog (@ "% @", [NSThread currentThread]);
// Obtain the global queue
Dispatch_queue_t queue = dispatch_get_global_queue (0, 0 );
// Perform asynchronous operations
Dispatch_async (queue, ^ {
NSLog (@ "% @", [NSThread currentThread]);
NSString * urlString = @ "http://design.yesky.com/uploadImages/2009/335/20091201140951681.jpg ";
NSData * data = [NSData dataWithContentsOfURL: [NSURL URLWithString: urlString];
UIImage * image = [UIImage imageWithData: data];
// Return to the main thread to update the UI
Dispatch_async (dispatch_get_main_queue (), ^ {
NSLog (@ "% @", [NSThread currentThread]);
Self. imageView. image = image;
});
});
}
-(Void) touchesBegan :( NSSet <UITouch *> *) touches withEvent :( UIEvent *) event {
// Synchronous operation purpose
Dispatch_queue_t queue = dispatch_get_global_queue (0, 0 );
Dispatch_sync (queue, ^ {
NSLog (@ "login ");
});
Dispatch_async (queue, ^ {
NSLog (@ "download a bucket ");
});
Dispatch_async (queue, ^ {
NSLog (@ "Download master ");
});
}