Catalogue iOS () multi-thread network-GCD download and merge image_queue group usage, iosgcd
CAT/CAT sharing, must be excellent
For Original Articles, please reprint them. Reprinted Please note: Yan Nai-yu's blog
Http://blog.csdn.net/u013357243? Viewmode = contents
Merge images (image watermarks) first method Effect
Implementation:
Ideas:
1. Download two images: large image and LOGO
2. merge two images
3. display on an imageView
// Download dispatch_async asynchronously (dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^ {// 1. download 1st NSURL * url1 = [NSURL URLWithString: @ "http://g.hiphotos.baidu.com/image/pic/item/f2deb48f8c5494ee460de6182ff5e0fe99257e80.jpg"]; NSData * data1 = [NSData dataWithContentsOfURL: url1]; UIImage * image1 = [UIImage imageWithData: data1]; // 2. download 2nd NSURL * url2 = [NSURL URLWithString: @ "http://su.bdimg.com/static/superplus/img/logo_white_ee663702.png"]; NSData * data2 = [NSData dataWithContentsOfURL: url2]; UIImage * image2 = [UIImage imageWithData: data2]; // 3. merge images // enable a bitmap context uigraphicsbeginimagecontextwitexceptions (image1.size, NO, 0.0); // draw 1st images CGFloat image1W = image1.size. width; CGFloat image1H = image1.size. height; [image1 drawInRect: CGRectMake (0, 0, image1W, image1H)]; // draw 2nd pictures CGFloat image2W = image2.size. width * 0.5; CGFloat image2H = image2.size. height * 0.5; CGFloat image2Y = image1H-image2H; [image2 drawInRect: CGRectMake (0, image2Y, image2W, image2H)]; // obtain the image UIImage * fullImage = UIGraphicsGetImageFromCurrentImageContext () in the Context; // end the context UIGraphicsEndImageContext (); // 4. return to the main thread to display the image dispatch_async (dispatch_get_main_queue (), ^ {self. imageView. image = fullImage ;});});
However, although this is done in the asynchronous thread, when the first graph is downloaded, the second graph is not yet downloaded, waiting, we want each image to be downloaded in a separate asynchronous thread, so we use the second method.
: Method 2
First, define two imageviews.
@property (weak, nonatomic) IBOutlet UIImageView *imageView;@property (nonatomic, strong) UIImage *image1;@property (nonatomic, strong) UIImage *image2;
Then implement
// Download dispatch_async asynchronously (dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^ {// 1. download 1st NSURL * url1 = [NSURL URLWithString: @ "http://g.hiphotos.baidu.com/image/pic/item/f2deb48f8c5494ee460de6182ff5e0fe99257e80.jpg"]; NSData * data1 = [NSData dataWithContentsOfURL: url1]; self. image1 = [UIImage imageWithData: data1]; [self bindImages];}); dispatch_async (dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^ {// 2. download 2nd NSURL * url2 = [NSURL URLWithString: @ "http://su.bdimg.com/static/superplus/img/logo_white_ee663702.png"]; NSData * data2 = [NSData dataWithContentsOfURL: url2]; self. image2 = [UIImage imageWithData: data2]; [self bindImages] ;});
The working principle is to enable two asynchronous threads to download two images respectively.
[Self bindImages] method. At this time, we set it back to the main interface for refresh in the s method, but first we need to determine whether the two graphs have data, as shown below:
-(Void) bindImages {if (self. image1 = nil | self. image2 = nil) return; // 3. merge images // enable a bitmap context uigraphicsbeginimagecontextwitexceptions (self. image1.size, NO, 0.0); // draw 1st images CGFloat image1W = self. image1.size. width; CGFloat image1H = self. image1.size. height; [self. image1 drawInRect: CGRectMake (0, 0, image1W, image1H)]; // draw 2nd pictures CGFloat image2W = self. image2.size. width * 0.5; CGFloat image2H = self. image2.size. height * 0.5; CGFloat image2Y = image1H-image2H; [self. image2 drawInRect: CGRectMake (0, image2Y, image2W, image2H)]; // obtain the image UIImage * fullImage = complete () in the Context; // end the context UIGraphicsEndImageContext (); // 4. return to the main thread to display the image dispatch_async (dispatch_get_main_queue (), ^ {self. imageView. image = fullImage ;});}
Although we solve the problem through our own ideas, we actually have a better solution, that is, the queue group.
Method 3: When will a queue group be used when the queue group is completed?
First, perform two time-consuming operations asynchronously.
Second, after two asynchronous operations are completed, return to the main thread to execute the operation.
To quickly and efficiently implement the preceding requirements, you can use a queue group as follows:
// 1. create a queue group dispatch_group_t group = dispatch_group_create (); // 2.1 The first queue group is asynchronous dispatch_group_async (group, dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0 ), ^ {// execute 1 time-consuming Asynchronous Operation}); // 2.2 The second queue group is asynchronous dispatch_group_async (group, dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0 ), ^ {// execute 1 time-consuming Asynchronous Operation}); // 3. after the asynchronous threads of all queue groups end, dispatch_group_notify (group, dispatch_get_main_queue (), ^ {// and other asynchronous operations are completed and then returned to the main thread ...});
Let's use the queue group to complete it. The Code is as follows:
// 1. queue group dispatch_group_t group = dispatch_group_create (); dispatch_queue_t queue = dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); // 2. download Picture 1 _ block UIImage * image1 = nil; dispatch_group_async (group, queue, ^ {NSURL * url1 = [NSURL URLWithString: @ "http://g.hiphotos.baidu.com/image/pic/item/f2deb48f8c5494ee460de6182ff5e0fe99257e80.jpg"]; NSData * data1 = [NSData dataWithContentsOfURL: url1]; image1 = [UIImage imageWithData: data1] ;}); // 3. download picture 2 _ block UIImage * image2 = nil; dispatch_group_async (group, queue, ^ {NSURL * url2 = [NSURL URLWithString: @ "http://su.bdimg.com/static/superplus/img/logo_white_ee663702.png"]; NSData * data2 = [NSData dataWithContentsOfURL: url2]; image2 = [UIImage imageWithData: data2] ;}); // 4. merge images (ensure that all tasks in the group are executed, and then execute the block in the notify function) dispatch_group_notify (group, queue, ^ {// enable a bitmap context uigraphicsbeginimagecontextwitexceptions (image1.size, NO, 0.0); // draw 1st images CGFloat image1W = image1.size. width; CGFloat image1H = image1.size. height; [image1 drawInRect: CGRectMake (0, 0, image1W, image1H)]; // draw 2nd pictures CGFloat image2W = image2.size. width * 0.5; CGFloat image2H = image2.size. height * 0.5; CGFloat image2Y = image1H-image2H; [image2 drawInRect: CGRectMake (0, image2Y, image2W, image2H)]; // obtain the image UIImage * fullImage = UIGraphicsGetImageFromCurrentImageContext () in the Context; // end the context UIGraphicsEndImageContext (); // 5. return to the main thread to display the image dispatch_async (dispatch_get_main_queue (), ^ {self. imageView. image = fullImage ;});});
_ Block keywords
Note: here we use the keyword _ block, because if it is not added, the block cannot access things outside the block.
Conclusion: Enable Asynchronization
(Directly press dispatch_a... There will be a bunch of prompts, and then you can choose to fill in, no difficulty, as mentioned above)
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ code});
Enable queue group:
First, create a queue group:
dispatch_group_t group = dispatch_group_create();
Then, replace the original place in the queue with the queue group and use dispatch_get_global_queue.
Dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^ {// execute 1 time-consuming Asynchronous Operation });
We can get a few more threads in the above section.
Then use this at the end:
Dispatch_group_notify (group, dispatch_get_main_queue (), ^ {// after all the preceding asynchronous operations are completed, return to the main thread ...});
Image merging process
Steps:
1. Enable a bitmap Context
2.1 draw 1st Images
2.2 draw 2nd Images
3. Get the image in the context
4. End Context
// 1. enable a bitmap context uigraphicsbeginimagecontextwitexceptions (image1.size, NO, 0.0); // 2.1 draw 1st pictures CGFloat image1W = image1.size. width; CGFloat image1H = image1.size. height; [image1 drawInRect: CGRectMake (0, 0, image1W, image1H)]; // 2.2 draw 2nd pictures CGFloat image2W = image2.size. width * 0.5; CGFloat image2H = image2.size. height * 0.5; CGFloat image2Y = image1H-image2H; [image2 drawInRect: CGRectMake (0, image2Y, image2W, image2H)]; // 3. obtain the image UIImage * fullImage = UIGraphicsGetImageFromCurrentImageContext (); // 4. end context UIGraphicsEndImageContext ();