线程之间的通信

我们在iOS开发中使用多线程一般使用这几种,NSThread,GCD,NSOperation;
我们多在自线程中进行数据加载或者下载的操作,所以总免不了将获取到的数据发送到主线程进行显示或者进行操作,下面就是我们经常使用基本的线程之间的通信;
 项目的准备工作:
     1.新建一个Xcode项目,在storybo
ard中创建一个image View,并设置约束和image view控件的大小,
关联到viewController的( @property (weak, nonatomic) IBOutlet UIImageView *imageview;)属性;
     2.在子线程下载的图片,然后显示到image view上;
 
第一种:NSThread

 

-(void)thread{
    // 创建一个字符串
    NSString *str = @"http://www.xiami.com/images/collect/802/2/10023802_1330239346.jpg";
    [self performSelectorInBackground:@selector(loadImage:) withObject:str];
}

-(void)loadImage:(NSString *)str{
   
    NSURL *url = [NSURL URLWithString:str];
    NSData *data = [NSData dataWithContentsOfURL:url];
    UIImage *image = [UIImage imageWithData:data];
   
    NSLog(@"loadImage----->%@",[NSThread currentThread]);
    /**
     *      这个方法回到主线程并且执行
     *  @param updateUI: 执行更新ui的方法
     */
    [self performSelectorOnMainThread:@selector(updateUI:) withObject:image waitUntilDone:NO];
}
-(void)updateUI:(UIImage *)image{
    self.imageview.image = image;
   
}

触发thread方法,performSelectorInBackground:withObject: ---->方法开启一个子线程,在子线程中执行  loadImage: 的方法,在loadImage中下载图片,然后调用performSelectorOnMainThread:withObject;回到主线程,在updateUI中将下载好的图片赋值给imageView;

 
第二种:GCD
//调用gcd
-(void)gcd{ NSString *str = @"http://www.xiami.com/images/collect/802/2/10023802_1330239346.jpg";
//在下面这个block使用self会形成循环引用,使用__weak修饰weakSelf,可以放置循环引用; //控制器对block有一个强引用,如果在block中使用self的话,block也对控制器有一个强引用; __weak typeof(self) weakSelf = self; /** * 开启一个异步任务, * 获取一个全局队列,在全局队列中下载图片 * 开启一个异步任务,在这个异步任务中获取一个主队列,在主队列中更新ui; */ dispatch_async(dispatch_get_global_queue(0, 0), ^{ NSURL *url = [NSURL URLWithString:str]; NSData *data = [NSData dataWithContentsOfURL:url]; UIImage *image = [UIImage imageWithData:data]; dispatch_async(dispatch_get_main_queue(), ^{ weakSelf.imageview.image = image; }); }); }

 

这个例子使用了两个简单的异步任务组合全局队列和主队列,进行下载操作和更新ui的操作;
 
第三种:NSoperation
 创建继承 NSOperation的文件,
DownLoadOperation.h
//  DownLoadOperation.h
//  线程之间的通信
//
//  Created by 两好三坏 on 16/2/21.
//  Copyright © 2016年 qinakun. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

typedef void(^FinishBlock)(UIImage *image);

@interface DownLoadOperation : NSOperation

//图片地址
@property(nonatomic,copy)  NSString *imageUrl;

@property(nonatomic,copy)  FinishBlock finishBlock;

@end

 

 DownLoadOperation.m
//
//  DownLoadOperation.m
//  线程之间的通信
//
//  Created by 两好三坏 on 16/2/21.
//  Copyright © 2016年 qinakun. All rights reserved.
//

#import "DownLoadOperation.h"

@implementation DownLoadOperation
-(void)main{
    @autoreleasepool {
        
        //1.1.拿着imageURLString去网络上下载
        NSURL *url = [NSURL URLWithString:self.imageUrl];
        
        //1.2.去网络上加载图片
        NSData *imageData = [NSData dataWithContentsOfURL:url];
        
        //1.3.将我们从网络上获取到的图片的二进制,转成UIImage
        UIImage *image = [UIImage imageWithData:imageData];
        
        if (self.finishBlock) {
            self.finishBlock(image);
        }
    }
}
@end

在控制器中的代码如下

-(void)operation{
    
    DownLoadOperation *operation = [DownLoadOperation new];
    
    operation.imageUrl = @"http://www.xiami.com/images/collect/802/2/10023802_1330239346.jpg";
    // 使用block, 
    operation.finishBlock = ^(UIImage *image){
        
        __weak typeof(self) weakSelf = self;
        
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
              weakSelf.imageview.image = image;
        }];
    };
}

  

 

 

posted @ 2016-02-21 22:06  两好三坏  阅读(636)  评论(0编辑  收藏  举报