iOS multi-threaded nsthread,nsoperation and GCD detailed

Source: Internet
Author: User
Tags gcd uikit

Threads are particularly useful when you need to perform a particularly time-consuming task, but you do not want it to block the execution of the rest of the program's functionality. In particular, you can use threads to avoid blocking the application's main thread from handling user interface events and the functions associated with the action. Threads can also be used to divide large work into smaller parts to improve the performance of the device.

Nsthread

Nsthread is relatively lightweight multithreaded development paradigm, but it is relatively complex to use, we need to manage the thread's life cycle, synchronization between threads.
In iOS development, we can implement Nsthread in the following three ways:
A. Dynamic instantiation

//动态创建NSThread- (void)dymaticCreateThread:(NSString *)url{    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(downLoadImage:) object:url];    [thread start];}

B. Static instantiation

//静态创建NSThread- (void)staticCreateThread:(NSString *)url{    [NSThread detachNewThreadSelector:@selector(downLoadImage:) toTarget:self withObject:url];}

C. Implicit instantiation

//在后台创建NSThread- (void)bkCreatThread:(NSString *)url{    [self performSelectorInBackground:@selector(downLoadImage:) withObject:url];}
- (void)downLoadImage:(NSString *)imageUrl{    NSURL *url = [NSURL URLWithString:imageUrl];    NSData *data = [NSData dataWithContentsOfURL:url];    //在主线程中更新界面    [self performSelectorOnMainThread:@selector(loadTheImage:) withObject:data waitUntilDone:YES];}- (void)loadTheImage:(NSData *)mdata{    self.imageBlock(mdata);}

The results are as follows:

When the button is clicked, a new thread is started and the image is downloaded, during which time it does not block the execution of the main thread. When the picture is downloaded, the UI thread is called to display the picture to the interface.

Nsoperation&nsoperationqueue

nsoperation is Apple's encapsulation of GCD, Nsoperation is just an abstract class that cannot be used to encapsulate tasks, so it needs to use its subclasses nsinvocationoperation and Nsblockoperation to encapsulate, there is no essential difference between the two ways, but the latter use block form of code organization, in the process of use more convenient.

You can see that nsoperation and Nsoperationqueue correspond to GCD tasks and queues respectively.
The procedure is also well understood:
1. The task to be performed is encapsulated into a Nsoperation object.
2. Add this task to a Nsoperationqueue column, and the thread will start in turn.

The sample code is as follows:

/ * *nsinvocationoperation Way * /- (void) Nsinvocationoperationtest: (NSString*) url{nsinvocationoperation *invaocationoperation = [[Nsinvocationoperation alloc] Initwithtarget: SelfSelector@selector(loadimage:) Object:url];    Nsoperationqueue *operationqueue = [[Nsoperationqueue alloc] init]; [Operationqueue addoperation:invaocationoperation];}/ * *nsblockoperation Way * /- (void) Nsblockoperationtest: (NSString*) url{Nsoperationqueue *operationqueue = [[Nsoperationqueue alloc] init];//// Create action block add to queue//Nsblockoperation *blockoperation = [Nsblockoperation blockoperationwithblock:^{//[self loadimage:url];//    }];//[Operationqueue addoperation:blockoperation];    //Use the action queue to add operations directly[Operationqueue addoperationwithblock:^{[ SelfLoadimage:url]; }];}

Nsblockoperation is recommended in comparison to Nsinvocationoperation, because it is simple in code, and because of the fact that the closure makes it not a reference problem, nsinvocationoperation is no longer supported in Swift.
The results are as follows:

Custom Inheritance Nsoperation, emphasis content implementation-(void) main function, a new thread to implement the image asynchronous download.

#import <Foundation/Foundation.h> #import <UIKit/UIKit.h>  @class loadimageoperation; @protocol loadimagedelegate <nsobject>- (void) Downloadoperation: (loadimageoperation *) operation Didfinishdownload: (NSData *) image;@end @interface loadimageoperation : nsoperation @property(Strong,nonatomic)NSString*imgurl;@property(Strong,nonatomic)ID<LoadImageDelegate> delegate;@end
#import "LoadImageOperation.h"  @implementation loadimageoperation @synthesizeImgurl = _imgurl;@synthesizeDelegate = _delegate;-(void) main{Nsurl*url = [NsurlURLWithString: Self. Imgurl]; NSData *data = [NSData Datawithcontentsofurl:url];if([ Self. DelegateRespondstoselector:@selector(downloadoperation:didfinishdownload:)]) {Dispatch_async(Dispatch_get_main_queue (), ^{[ Self. DelegateDownloadoperation: SelfDidfinishdownload:data];    }); }}@end

The following code is the calling method:

- (IBAction)buttomClick:(id)sender {    self.imageView.imagenil;    LoadImageOperation *loadtest = [[LoadImageOperation alloc] init];    loadtest.imgUrl = @"http://img.blog.csdn.net/20160622181936607";    loadtest.delegateself;    NSOperationQueue *operationqueue = [[NSOperationQueue alloc] init];    [operationqueue addOperation:loadtest];}

The results are as follows:

nsoperation dependency
When the Nsoperation object needs to be dependent on the other Nsoperation object when it is finished, You can add one or more dependent objects through the Adddependency method, and only the beginning of the Nsoperation object will start executing after all dependent objects have finished, removing the dependent objects through removedependency. Multithreaded development with Nsoperation also allows you to set the maximum concurrent threads, effectively controlling the threads.

-(void) Depandencetest: (Nsarray *) urlarray{int count = 5 ;    Create an action queue nsoperationqueue *operationqueue = [[nsoperationqueue alloc] init];    Sets the maximum number of concurrent threads Operationqueue.maxconcurrentoperationcount = 5; Nsblockoperation *lastblockoperation = [Nsblockoperation blockoperationwithblock:^{[Self LoadImage:[urlArray objec    TATINDEX:COUNT-1]] ;    }]; for  (int i = 0 ; i < count-1 ; i++) {Nsblockoperation *blockoperation = [Nsblockoperation blockoperationwithblock:^{[Self loadimage:[urlar        Ray Objectatindex:i]];        }];        Set dependency action [Blockoperation adddependency:lastblockoperation];    [Operationqueue addoperation:blockoperation]; }//Add the last action to the thread queue [Operationqueue addoperation:lastblockoperation];}  
GCD

Grand Central Dispatch (GCD), which is a solution for Apple's multi-core parallel operation, will automatically rationalize the use of more CPU cores and, more importantly, automatically manage the lifecycle of threads (create threads, dispatch tasks, destroy threads).

When you start using GCD, you need to figure out the concepts of tasks and queues.
There are two ways to perform a task :
1. Synchronous operation (sync), which blocks the operation of the current thread and waits for the task in the block to complete before the current thread continues to execute.
2. Asynchronous operation (async), the current thread executes directly down, not blocking the current thread.

The queue also has two queues, the serial queue and the parallel queue
Serial Queue : Follow the FIFO principle, take out a execute one, create a serial queue when the function dispatch_queue_create is created, where the first parameter is the identifier, the second parameter is used to indicate whether the created queue is serial or parallel, the incoming Dispatch_queue_serial or NULL indicates the creation of a serial queue.

The code is as follows:

    //创建一个串行队列    //第一个参数 创建队列名称,方便Debug    //第二个参数 对列类型 DISPATCH_QUEUE_SERIAL(串行)DISPATCH_QUEUE_CONCURRENT(并发,实际上不使用该方式创建)    dispatch_queue_t serialQueue = dispatch_queue_create("myThread", DISPATCH_QUEUE_SERIAL);    dispatch_async(serialQueue, ^{        [self loadImage:url];    });

parallel Queues : The FIFO principle is also followed, but the difference is that it puts the extracted tasks into the other threads and then takes them out to another thread. When creating a concurrent queue, you can also create a function dispatch_queue_create, passing in dispatch_queue_concurrent to create a parallel queue. But in the actual development we will get a global concurrency queue through the Dispatch_get_global_queue () method, the system provides 3 concurrent queues for each application, and they are all global, but each queue has a different priority, namely:

Define Dispatch_queue_priority_high 2 Highest priority

Define Dispatch_queue_priority_default 0 Priority medium

Define Dispatch_queue_priority_low (-2) Lowest priority

    //创建一个并行队列    //线程优先级    //传0    dispatch_queue_t0);    dispatch_async(globalQueue, ^{        [self loadImage:url];    });
- (void)loadImage:(NSString *)url{    NSURL *mUrl = [NSURL URLWithString:url];    NSData *data = [NSData dataWithContentsOfURL:mUrl];    dispatch_async(dispatch_get_main_queue(), ^{        self.block(data);    });}

The results are as follows:

in GCD There is also a special queue ——— the home row, which is used to perform operations on the main thread, Dispatch_get_main_queue () which is a globally available serial queue.

In addition GCD has other task execution methods:
Dispatch_group_async (queue Group) usage, queue groups can add many queues to a group, and the benefit is that when all the tasks in the group are executed, the queue group is notified by the Dispatch_group_notify () method.

Dispatch_barrier_async (): The write operation ensures that the operation before the queue starts and blocks subsequent operations in the queue. It will not execute until it finishes executing.

Dispatch_apply (): Executes a task repeatedly.

Dispatch_once (): Performs one task at a time, the task in this method is executed only once, repeated calls are not repeated, and this method is commonly used in singleton mode.

Dispatch_time (): Executes after a certain amount of time has been delayed.

Perhaps the above operation effect people do not realize the effect of multi-threaded implementation of the image asynchronous loading, Next I will add 6 uiimageview in the view, open 6 threads, respectively, to load the image uiimageview.

The results are as follows:

The sample code is as follows:

#import "ShowExampleViewController.h"  @interface showexampleviewcontroller ()@end @implementation showexampleviewcontroller @synthesizeImagesarray = _imagesarray;@synthesizeUrlarrays = _urlarrays;-(void) Viewdidload {[SuperViewdidload];additional setup after loading the view from its nib.     Self. Urlarrays= [[NsmutablearrayAlloc] initwithobjects:@"Http://img1.gtimg.com/14/1492/149249/14924912_980x1200_0.jpg",                      @"Http://img1.gtimg.com/14/1492/149249/14924914_980x1200_0.jpg",                      @"Http://img1.gtimg.com/14/1492/149249/14924916_980x1200_0.jpg",                      @"Http://img1.gtimg.com/14/1492/149249/14924917_980x1200_0.jpg",                      @"Http://img1.gtimg.com/14/1492/149249/14924918_980x1200_0.jpg",                      @"Http://img1.gtimg.com/14/1492/149249/14924919_980x1200_0.jpg",Nil]; [Nsoperationtest getinstance]. Delegate= Self; [ SelfLayoutui];} - (void) Didreceivememorywarning {[SuperDidreceivememorywarning];//Dispose of any resources, can be recreated.}- (void) layoutui{ Self. Imagesarray= [[NsmutablearrayALLOC] init]; for(intR=0; r<2; r++) { for(intC=0; c<3; C + +) {Uiimageview*imageview=[[UiimageviewAlloc]initwithframe:cgrectmake (c* -+ (c*Ten), r* -+ (r*Ten) + -, -, -)]; ImageView. Contentmode=uiviewcontentmodescaleaspectfit; [ Self. ViewAddsubview:imageview];        [_imagesarray Addobject:imageview]; }    }}-(void) UpdateImage: (NSData *) ImageData Index: (int) index{UIImage*image=[UIImageImagewithdata:imagedata];Uiimageview*imageview = _imagesarray[index]; ImageView. Image= Image;} - (ibaction) Clickloadimage: (ID) Sender { for(inti =0; i < [ Self. UrlarraysCount]; i++) {[[Nsoperationtest getinstance] nsblockoperationtest:[ Self. UrlarraysOBJECTATINDEX:I] index:i]; }}- (void) Downloadoperation: (loadimageoperation *) operation Didfinishdownload: (NSData *) image{}-(void) Downloadoperation: (loadimageoperation *) operation Didfinishdownload: (NSData *) image Index: (int) index{[ SelfUpdateimage:image Index:index];}@end

For iOS multi-threaded operations, let's talk about this! Follow up if there is new content I will update it regularly.

You are welcome to pay attention to my public number, what problems can be contacted at any time, scan the following QR code to add:

iOS multi-threaded nsthread,nsoperation and GCD detailed

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.