您的位置:首页 > 其它

线程之间的通信

2016-02-21 22:06 746 查看
我们在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;
}];
};
}


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: