在实际的项目开发中,我们往往需要从网络加载图片资源,为了不影响主线程,我们需要开辟新的线程。同时为了控制不同线程之间的前后顺序,需要引入信号量机制。这里我们来实现一个案例:从网络加载3张图片,当加载完第一张后在加载第二张,然后再加载第三张。项目我放在了 https://github.com/chenyufeng1991/GCD 。中的GCD06.实现如下:
(1)首先需要引入GCD封装后的代码,其实个人推荐使用iOS原生的GCD,请移步《iOS开发——GCD的使用与多线程开发浅析》这篇博客。然后在ViewController代码中实现如下:
#import "ViewController.h"
#import "GCD.h"
@interface ViewController ()
@property(strong,nonatomic) UIImageView *view1;
@property(strong,nonatomic) UIImageView *view2;
@property(strong,nonatomic) UIImageView *view3;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view1 = [self setImageViewFrame:CGRectMake(0, 0, 300, 200)];
self.view2 = [self setImageViewFrame:CGRectMake(0, 200, 300, 200)];
self.view3 = [self setImageViewFrame:CGRectMake(0, 400, 300, 200)];
NSString *url01 = @"http://pic17.nipic.com/20111026/8662498_125925242183_2.jpg";
NSString *url02 = @"http://b.hiphotos.baidu.com/zhidao/wh%3D450%2C600/sign=53da5874352ac65c67506e77cec29e27/9f2f070828381f30807909bda9014c086e06f046.jpg";
NSString *url03 = @"http://cimg.163.com/sport/0412/23/wu2305.jpg";
GCDSemaphore *semaphore = [[GCDSemaphore alloc] init];
GCDSemaphore *semaphore2 = [[GCDSemaphore alloc] init];
//开启三个异步线程;
[GCDQueue executeInGlobalQueue:^{
UIImage *image01 = [self accessDataByNetwork:url01];
[GCDQueue executeInMainQueue:^{
[UIView animateWithDuration:2.0f
animations:^{
self.view1.image = image01;
[self.view1 setAlpha:1.0f];
} completion:^(BOOL finished) {
//通知第1个信号量;
[semaphore signal];
}];
}];
}];
[GCDQueue executeInGlobalQueue:^{
UIImage *image02 = [self accessDataByNetwork:url02];
//第1个信号量等待;
[semaphore wait];
[GCDQueue executeInMainQueue:^{
[UIView animateWithDuration:2.0f
animations:^{
self.view2.image = image02;
[self.view2 setAlpha:1.0f];
} completion:^(BOOL finished) {
//通知第2个信号量;
[semaphore2 signal];
}];
}];
}];
[GCDQueue executeInGlobalQueue:^{
UIImage *image03 = [self accessDataByNetwork:url03];
//第2个信号量等待;
[semaphore2 wait];
[GCDQueue executeInMainQueue:^{
[UIView animateWithDuration:2.0f
animations:^{
self.view3.image = image03;
[self.view3 setAlpha:1.0f];
} completion:^(BOOL finished) {
}];
}];
}];
}
//设置图片大小位置和透明度;alpha = 0表示完全透明;
- (UIImageView *)setImageViewFrame:(CGRect)frame{
UIImageView *imageView = [[UIImageView alloc] initWithFrame:frame];
imageView.alpha = 0.f;
[self.view addSubview:imageView];
return imageView;
}
//进行网络请求;
- (UIImage *)accessDataByNetwork:(NSString *)string{
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:string]];
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
return [UIImage imageWithData:data];
}
@end
(2)运行效果如下:
。
。
。
(3)结果分析:
为了效果看起来比较明显,我在每张图片进行显示的时候设置了2s的动画,并且有渐变的效果。
同时这里需要设置2个信号量semaphore。这样才会有一个同步的作用。
github主页:https://github.com/chenyufeng1991 。欢迎大家访问!