iOS-多线程--介绍NSThread和GCD及其它们的线程通讯示例
前言:下面就不一一列出 pthread、NSThread、GCD、NSOperation 的完整的各种方法了,只分别将最常用的列出来,以便偶尔瞄一眼。
一、NSThread
1> 线程间的通讯
/** 这个例子为在创建的子线程中下载图片,然后回到主线程中设置图片 ( 更新UI ) */
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
// 隐式创建并启动线程
[self performSelectorInBackground:@selector(download) withObject:nil];
}
/**
* 图片下载
*/
- (void)download
{
NSLog(@"download---%@", [NSThread currentThread]);
// 1.图片地址
NSString *urlStr = @"http://d.hiphotos.baidu.com/image/pic/item/37d3d539b6003af3290eaf5d362ac65c1038b652.jpg";
NSURL *url = [NSURL URLWithString:urlStr];
// 2.根据地址下载图片的二进制数据(耗时的代码)
NSLog(@"---begin");
NSData *data = [NSData dataWithContentsOfURL:url];
NSLog(@"---end");
// 3.设置图片
UIImage *image = [UIImage imageWithData:data];
// 4.回到主线程,刷新UI界面(为了线程安全)
[self performSelectorOnMainThread:@selector(downloadFinished:) withObject:image waitUntilDone:NO];
// [self performSelector:@selector(downloadFinished:) onThread:[NSThread mainThread] withObject:image waitUntilDone:YES];
// [self.imageView performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:YES];
NSLog(@"-----over----");
}
- (void)downloadFinished:(UIImage *)image
{
self.imageView.image = image;
NSLog(@"downloadFinished---%@", [NSThread currentThread]);
}
@end
/****************************分割线****************************/
二、GCD
1> 、GCD 【 (任务)同步/异步***(队列)串行/并发*****任务和队列的几种组合方式 】
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self asyncSerialQueue];
}
// 就下面三个最常用,(GCD中其他情况不要管)
/**
* 第一种组合方式
* async -- 并发队列(最常用)
* 会不会创建线程:会,一般同时开多条
* 任务的执行方式:并发执行
*/
- (void)asyncGlobalQueue
{
// 获得全局的并发队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// 将 任务 添加 全局队列 中去 异步 执行
dispatch_async(queue, ^{
NSLog(@"-----下载图片1---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下载图片2---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下载图片3---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下载图片4---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下载图片5---%@", [NSThread currentThread]);
});
}
/**
*第一种组合方式 打印结果
2016-04-07 17:48:05.007 Test-GCD测试一下[909:50754] -----下载图片2---<NSThread: 0x7f8acb50ea50>{number = 3, name = (null)}
2016-04-07 17:48:05.007 Test-GCD测试一下[909:50755] -----下载图片1---<NSThread: 0x7f8acb4bedf0>{number = 2, name = (null)}
2016-04-07 17:48:05.007 Test-GCD测试一下[909:50762] -----下载图片4---<NSThread: 0x7f8acb71b570>{number = 5, name = (null)}
2016-04-07 17:48:05.007 Test-GCD测试一下[909:50763] -----下载图片5---<NSThread: 0x7f8acb510160>{number = 6, name = (null)}
2016-04-07 17:48:05.007 Test-GCD测试一下[909:50758] -----下载图片3---<NSThread: 0x7f8acb60e780>{number = 4, name = (null)}
*/
/**
* 第二种组合方式
* async -- 串行队列(有时候用)
* 会不会创建线程:会,一般只开1条线程
* 任务的执行方式:串行执行(一个任务执行完毕后再执行下一个任务)
*/
- (void)asyncSerialQueue
{
// 1.创建一个串行队列
dispatch_queue_t queue = dispatch_queue_create("cn.heima.queue", NULL);
// 2.将任务添加到串行队列中 异步 执行
dispatch_async(queue, ^{
NSLog(@"-----下载图片1---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下载图片2---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下载图片3---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下载图片4---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下载图片5---%@", [NSThread currentThread]);
});
// 3.非ARC,需要释放创建的队列
// dispatch_release(queue);
}
/**
* 第二种方式 打印结果
2016-04-07 17:49:33.730 Test-GCD测试一下[921:52233] -----下载图片1---<NSThread: 0x7f926ad09e20>{number = 2, name = (null)}
2016-04-07 17:49:33.731 Test-GCD测试一下[921:52233] -----下载图片2---<NSThread: 0x7f926ad09e20>{number = 2, name = (null)}
2016-04-07 17:49:33.731 Test-GCD测试一下[921:52233] -----下载图片3---<NSThread: 0x7f926ad09e20>{number = 2, name = (null)}
2016-04-07 17:49:33.731 Test-GCD测试一下[921:52233] -----下载图片4---<NSThread: 0x7f926ad09e20>{number = 2, name = (null)}
2016-04-07 17:49:33.731 Test-GCD测试一下[921:52233] -----下载图片5---<NSThread: 0x7f926ad09e20>{number = 2, name = (null)}
*/
/**
* 第三种方式 (这是一种特殊的方式,将 任务 添加到主队列中 异步 执行)
* async -- 主队列(很常用) (一般在线程之间的通讯才用得上 @xz)
*/
- (void)asyncMainQueue
{
// 1.主队列(添加到主队列中的任务,都会自动放到主线程中去执行)
dispatch_queue_t queue = dispatch_get_main_queue();
// 2.添加 任务 到主队列中 异步 执行
dispatch_async(queue, ^{
NSLog(@"-----下载图片1---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下载图片2---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下载图片3---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下载图片4---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下载图片5---%@", [NSThread currentThread]);
});
}
/**
* 第三种方式 打印结果如下:
2016-04-07 16:50:04.245 Test-GCD测试一下[801:31778] -----下载图片1---<NSThread: 0x7fb2a2d0a1e0>{number = 1, name = main}
2016-04-07 16:50:04.246 Test-GCD测试一下[801:31778] -----下载图片2---<NSThread: 0x7fb2a2d0a1e0>{number = 1, name = main}
2016-04-07 16:50:04.246 Test-GCD测试一下[801:31778] -----下载图片3---<NSThread: 0x7fb2a2d0a1e0>{number = 1, name = main}
2016-04-07 16:50:04.247 Test-GCD测试一下[801:31778] -----下载图片4---<NSThread: 0x7fb2a2d0a1e0>{number = 1, name = main}
2016-04-07 16:50:04.248 Test-GCD测试一下[801:31778] -----下载图片5---<NSThread: 0x7fb2a2d0a1e0>{number = 1, name = main}
*/
2> GCD------线程间通讯示例
注意点:
<1>. 需要设置按钮的image和backgroundImage,建议先把按钮类型改为custom,才能保证设置成功
<2>. 属性名不能以new开头
<3>. 只有在init开头的构造方法中,才允许对self进行赋值
#define XZGlobalQueue dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
#define XZMainQueue dispatch_get_main_queue()
#import "XZViewController.h"
@interface XZViewController ()
@property (weak, nonatomic) IBOutlet UIButton *button;
@end
@implementation XZViewController
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(20, 20, 100, 60)];
[self.view addSubview:button];
self.button = button;
dispatch_async(XZGlobalQueue, ^{
NSLog(@"donwload---%@", [NSThread currentThread]);
// 1.子线程下载图片
NSURL *url = [NSURL URLWithString:@"http://d.hiphotos.baidu.com/image/pic/item/37d3d539b6003af3290eaf5d362ac65c1038b652.jpg"];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];
// 2.回到主线程设置图片
dispatch_async(XZMainQueue, ^{
NSLog(@"setting---%@ %@", [NSThread currentThread], image);
[self.button setImage:image forState:UIControlStateNormal];
});
});
}
@end
/*
* 打印结果
Test-GCD测试一下[873:44012] donwload---<NSThread: 0x7fc7a0401d50>{number = 2, name = (null)}
Test-GCD测试一下[873:43920] setting---<NSThread: 0x7fc7a0507930>{number = 1, name = main} <UIImage: 0x7fc7a0681530>, {440, 608}
*/
/****************************分割线****************************/
iOS-多线程--介绍NSThread和GCD及其它们的线程通讯示例的更多相关文章
- iOS多线程开发--NSThread NSOperation GCD
多线程 当用户播放音频.下载资源.进行图像处理时往往希望做这些事情的时候其他操作不会被中 断或者希望这些操作过程中更加顺畅.在单线程中一个线程只能做一件事情,一件事情处理不完另一件事就不能开始,这样势 ...
- iOS 多线程(NSThread、GCD、NSOperation)
ios中得多线程技术主要使用3种:NSThread.NSOperation和GCD 一.NSThread: 最轻量级方法,但是不安全需要手动加锁,需要自己管理生命周期 NSThread的使用方法有2种 ...
- iOS的三种多线程技术NSThread/NSOperation/GCD
1.iOS的三种多线程技术 1.NSThread 每个NSThread对象对应一个线程,量级较轻(真正的多线程) 2.以下两点是苹果专门开发的"并发"技术,使得程序员可以不再去关心 ...
- 多线程技术 NSThread & NSOperation & GCD
多线程:在iOS开发中,用到多线程的处理问题的时候有很多,比如异步下载数据时刷新界面等等. 引入多线程来处理问题的关键就是,基于多线程可以使界面更加流畅,防止界面假死. 界面假死:比如你单击一个按钮来 ...
- iOS多线程(上)——GCD详解(上)
GCD(Grand central Dispatch)是Apple开发的一个多核编程的较新的解决方法.它主要用于优化应用程序以支持多核处理器以及其他对称多处理系统.下面我讲讲述关于GCD的点,通篇读完 ...
- iOS 多线程之 NSThread的基本使用
一个NSThread对象就代表一条线程 下面是NSThread开启线程的方法 - (void)touchesBegan:(NSSet<UITouch *> *)touches withEv ...
- IOS多线程(NSThread)
1.创建方法 使用NSThread创建线程主要有两个个方法,分别如下 NSThread* myThread = [[NSThread alloc] initWithTarget:self sele ...
- iOS多线程介绍
一.线程概述 有些程序是一条直线,起点到终点:有些程序是一个圆,不断循环,直到将它切断.直线的如简单的Hello World,运行打印完,它的生命周期便结束了,像昙花一现那样:圆如操作系统,一直运行直 ...
- 多线程&NSObject&NSThread&NSOperation&GCD
1.NSThread 每个NSThread对象对应一个线程,量级较轻(真正的多线程) 以下两点是苹果专门开发的“并发”技术,使得程序员可以不再去关心线程的具体使用问题 2.NSOperation/NS ...
随机推荐
- android xmlns:tools用法
一开始不明白,后来删掉这个属性之后发现会出现一个提示: pick preview layout from the "Fragment Layout" context menu 原来 ...
- HTML5探索一(那些新增的标签和属性)
tml5相比html4,添加了部分语义化的标签和属性,现在我们就从这些标签和属性开始,学习html5吧. 首先,认识下HTML5新的文档类型: <!DOCTYPE html> 那些新标签 ...
- DDD:两篇不错的文章
文章列表 Coding for Domain-Driven Design: Tips for Data-Focused Devs. Strengthening your domain: Aggrega ...
- js时间对象格式化 format(转载)
/** * 时间对象的格式化 */ Date.prototype.format = function(format){ /* * format="yyyy-MM-dd hh:mm:ss&qu ...
- IOS开发UI基础UITextView相关属性
UITextView相关属性 • text: 设置textView中文本_textView.text = @"Now is the time for all good develope ...
- 存储过程分页 Ado.Net分页 EF分页 满足90%以上
存储过程分页: create proc PR_PagerDataByTop @pageIndex int, @pageSize int, @count int out as select top(@p ...
- vs.net_2003 下载 虽然是老古董了,但还是很有用的。
系统要求 支持的操作系统: Windows 2000; Windows NT; Windows Server 2003; Windows XP 以下VS2003的下载链接: http://bcsoft ...
- 面向对象的JavaScript(3):私有成员和公开成员
在小项目中对于JavaScript使用,只要写几个function就行了.但在大型项目中,尤其是在开发追求 良好的用户体验的网站中,如SNS,就会 用到大量的JavaScrpt,有时JavaScrip ...
- Vector Clock/Version Clock
physical clock 机器上的物理时钟,不同的机器在同一个时间点取到的physical clock不一样,之间会存在一定的误差,NTP可以用来控制这个误差,同一个机房内的机器之间的时钟误差可以 ...
- 【Unity】13.1 场景视图中的GI可视化
分类:Unity.C#.VS2015 创建日期:2016-05-19 一.简介 在场景视图中设计不同的场景内容时,可以根据需要勾选相关的渲染选项,以便让场景仅显示其中的一部分或者全部渲染效果. 在这些 ...