GCD实践——多线程图片下载与信号量开发实践

      在实际的项目开发中,我们往往需要从网络加载图片资源,为了不影响主线程,我们需要开辟新的线程。同时为了控制不同线程之间的前后顺序,需要引入信号量机制。这里我们来实现一个案例:从网络加载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  。欢迎大家访问!






















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值