你的位置:首页 > 操作系统

[操作系统]线程之间的通信


我们在iOS开发中使用多线程一般使用这几种,NSThread,GCD,NSOperation;
我们多在自线程中进行数据加载或者下载的操作,所以总免不了将获取到的数据发送到主线程进行显示或者进行操作,下面就是我们经常使用基本的线程之间的通信;
 项目的准备工作:
     1.新建一个Xcode项目,在storyboard中创建一个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;    }];  };}