iOS--多线程之线程间通讯
线程间通讯
一、NSThread
1.简单说明
①线程间通信:在1个进程中,线程往往不是孤立存在的,多个线程之间需要经常进行通信
②线程间通信的体现
- 1个线程传递数据给另1个线程
- 在1个线程中执行完特定任务后,转到另1个线程继续执行任务
③线程间通信常用方法
// waitUntilDone的含义:
// 如果传入的是YES: 那么会等到主线程中的方法执行完毕, 才会继续执行下面其他行的代码
// 如果传入的是NO: 那么不用等到主线程中的方法执行完毕, 就可以继续执行下面其他行的低吗
/*
* 回到主线程执行,执行self的showImage方法,参数是image
*/
[self performSelectorOnMainThread:@selector(showImage:) withObject:image waitUntilDone:YES];
/*
* 回到xx线程执行aSelector方法,参数是arg
*/
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait;
④案例,下载图片,然后在屏幕上显示
注意:虽然有时候可以在子线程中操作UI,但是开发中千万不要这样干因为如果是在子线程中操作UI, 有时候行, 有时候不行
- (void)viewDidLoad
{
// 1.给定图片的url
NSURL *url = [NSURL URLWithString:@"http://b.hiphotos.baidu.com/image/pic/item/e4dde71190ef76c666af095f9e16fdfaaf516741.jpg"];
// 2.开启线程,在后台执行download方法
[self performSelectorInBackground:@selector(download:) withObject:url];
}
- (void)download:(NSURL *)url
{
// 在子线程下载图片
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];
// 设置图片,执行self.imageView的setImage:方法
// [self.imageView performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:YES];
// 另一张设置图片的方法
// 回到主线程中执行 showImage:方法,在此方法中设置图片
[self performSelector:@selector(showImage:) onThread:[NSThread mainThread] withObject:image waitUntilDone:YES];
}
-(void)showImage:(UIImage *)image
{
// 更新UI
self.imageView.image = image;
}
几个常用打印时间的方法
//获得当前时间,double型
CFAbsoluteTime begin = CFAbsoluteTimeGetCurrent();
// 获得当前时间
NSDate *begin = [NSDate date];
// 执行一些操作之后的时间
NSDate *end = [NSDate date];
// 时差
NSLog(@"花费了多少秒 %f", [end timeIntervalSinceDate:begin]);
二、GCD
- 案例,下载图片,然后在屏幕上显示
在dispatch_get_main_queue() 队列中
如果是通过异步函数调用, 那么会先执行完所有的代码, 再更新UI
如果是同步函数调用, 那么会先更新UI, 再执行其它代码
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
// 1.下载图片(耗时)
dispatch_async(queue, ^{
NSLog(@"%@", [NSThread currentThread]);
// 1.创建URL
NSURL *url = [NSURL URLWithString:@"http://stimgcn1.s-msn.com/msnportal/ent/2015/08/04/7a59dbe7-3c18-4fae-bb56-305dab5e6951.jpg"];
// 2.通过NSData下载图片
NSData *data = [NSData dataWithContentsOfURL:url];
// 3.将NSData转换为图片
UIImage *image = [UIImage imageWithData:data];
// 4.更新UI
// self.imageView.image = image;
// NSLog(@"更新UI完毕");
// 如果是通过异步函数调用, 那么会先执行完所有的代码, 再更新UI
// 如果是同步函数调用, 那么会先更新UI, 再执行其它代码
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"%@", [NSThread currentThread]);
self.imageView.image = image;
NSLog(@"更新UI完毕");
});
NSLog(@"Other");
});
三、NSOperation
1.第一种方法
// 1.创建一个新的队列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
// 2.添加任务(操作)
[queue addOperationWithBlock:^{
// 2.1在子线程中下载图片
NSURL *url = [NSURL URLWithString:@"http://imgcache.mysodao.com/img2/M04/8C/74/CgAPDk9dyjvS1AanAAJPpRypnFA573_700x0x1.JPG"];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];
// 2.2回到主线程更新UI
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
self.imageView.image = image;
}];
}];
2.第二种方法(添加依赖)
/ 1.创建一个队列
// 一般情况下, 在做企业开发时候, 都会定义一个全局的自定义队列, 便于使用
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
// 2.添加一个操作下载第一张图片
__block UIImage *image1 = nil;
NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
NSURL *url = [NSURL URLWithString:@"http://imgcache.mysodao.com/img2/M04/8C/74/CgAPDk9dyjvS1AanAAJPpRypnFA573_700x0x1.JPG"];
NSData *data = [NSData dataWithContentsOfURL:url];
image1 = [UIImage imageWithData:data];
}];
// 3.添加一个操作下载第二张图片
__block UIImage *image2 = nil;
NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
NSURL *url = [NSURL URLWithString:@"http://imgcache.mysodao.com/img1/M02/EE/B5/CgAPDE-kEtqjE8CWAAg9m-Zz4qo025-22365300.JPG"];
NSData *data = [NSData dataWithContentsOfURL:url];
image2 = [UIImage imageWithData:data];
}];
// 4.添加一个操作合成图片
NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
UIGraphicsBeginImageContext(CGSizeMake(200, 200));
[image1 drawInRect:CGRectMake(0, 0, 100, 200)];
[image2 drawInRect:CGRectMake(100, 0, 100, 200)];
UIImage *res = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// 5.回到主线程更新UI
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
self.imageView.image = res;
}];
}];
// 6.添加依赖
[op3 addDependency:op1];
[op3 addDependency:op2];
// 7.添加操作到队列中
[queue addOperation:op1];
[queue addOperation:op2];
[queue addOperation:op3];
iOS--多线程之线程间通讯的更多相关文章
- 黑马程序员——JAVA基础之多线程的线程间通讯等
------- android培训.java培训.期待与您交流! ---------- 线程间通讯: 其实就是多个线程在操作同一个资源,但是动作不同. wait(); 在其他线程调用此对象的notif ...
- 【原】iOS多线程之线程间通信和线程互斥
线程间通信 1> 线程间通信分为两种 主线程进入子线程(前面的方法都可以) 子线程回到主线程 2> 返回主线程 3> 代码 这个案例的思路是:当我触摸屏幕时,会在子线程加载图片,然后 ...
- Android 异步任务,通过PHP访问数据库,多线程,线程间通讯
文章列表MainActivity.java package com.eric.asynctask; import java.io.IOException; import java.util.Array ...
- iOS开发多线程-线程间通讯
一.NSThread 线程间的通讯 - (void)demoAboutNSThread { NSLog(@"demoAboutNSThread %@", [NSThread cur ...
- java 并发性和多线程 -- 读感 (二 线程间通讯,共享内存的机制)
参考文章:http://ifeve.com/java-concurrency-thread-directory/ 其中的竞态,线程安全,内存模型,线程间的通信,java ThreadLocal类小节部 ...
- Java:多线程<三>死锁、线程间通讯
死锁: 同步嵌套同步,而且使用的锁不是同一把锁时就可能出现死锁 class Test implements Runnable { private boolean flag; Test(boolean ...
- iOS开发多线程篇—线程间的通信
iOS开发多线程篇—线程间的通信 一.简单说明 线程间通信:在1个进程中,线程往往不是孤立存在的,多个线程之间需要经常进行通信 线程间通信的体现 1个线程传递数据给另1个线程 在1个线程中执行完特定任 ...
- 【转】JAVA 并发性和多线程 -- 读感 (二 线程间通讯,共享内存的机制)
原文地址:https://www.cnblogs.com/edenpans/p/6020113.html 参考文章:http://ifeve.com/java-concurrency-thread-d ...
- (转载)Java里快如闪电的线程间通讯
转自(http://www.infoq.com/cn/articles/High-Performance-Java-Inter-Thread-Communications) 这个故事源自一个很简单的想 ...
- Java中快如闪电的线程间通讯
这个故事源自一个很简单的想法:创建一个对开发人员友好的.简单轻量的线程间通讯框架,完全不用锁.同步器.信号量.等待和通知,在Java里开发一个轻量.无锁的线程内通讯框架:并且也没有队列.消息.事件或任 ...
随机推荐
- ASP.NET MVC 提供与访问 Web Api
ASP.NET MVC 提供与访问 Web Api 一.提供一个 Web Api 新建一个项目,类型就选 "Web Api".我用的是MVC5,结果生成的项目一大堆东西,还编译不过 ...
- 2016/05/10 thinkphp 3.2.2 ①系统常量信息 ②跨控制器调用 ③连接数据库配置及Model数据模型层 ④数据查询
[系统常量信息] 获取系统常量信息: 如果加参数true,会分组显示: 显示如下: [跨控制器调用] 一个控制器在执行的时候,可以实例化另外一个控制,并通过对象访问其指定方法. 跨控制器调用可以节省我 ...
- myeclipse包的层数和package的层数不一致
复制别人的工程的时候常常遇到包的层数不一致的情况 如下图 其实com.weibo.happpy.dao的上面还有一层java包,但是代码里没有写java....... 可以通过如下方式修改工程:
- [m() for i in range(8)]
import time def m(): print(time.time()) time.sleep(1) [m() for i in range(8)] 一行 list
- (1)JDBC基础-java链接mysql数据库
怎么操作数据库: 1,通过客户端(比如mac的终端,或者sql pro等专业工具)登陆数据库服务器(mysql -u root -p) 2,编写sql语句 3,发生sql语句到数据库服务器执行. JD ...
- POJ1984 Navigation Nightmare —— 种类并查集
题目链接:http://poj.org/problem?id=1984 Navigation Nightmare Time Limit: 2000MS Memory Limit: 30000K T ...
- YTU 2946: 填空:间接基类就是A
2946: 填空:间接基类就是A 时间限制: 1 Sec 内存限制: 128 MB 提交: 132 解决: 96 题目描述 如下程序所示,D继承自B和C,而B和C均继承自A.根据继承的机制,D的对 ...
- 如何用Mac远程桌面连接windows
打开mac,连接网络,找到系统中自带的“远程桌面连接”软件,截图如下
- Pimple研究及PHP框架搭建
此文参考PHP容器--Pimple运行流程浅析 和 利用 Composer 一步一步构建自己的 PHP 框架,如有不清楚的,请参考原文. Pimple貌似在PHP社区里非常流行,听闻是个非常轻量化并且 ...
- WEB开发框架系列教程 (三)页面功能开发(2)
上一节介绍了,基础资料币别信息的开发,只通过辅助开发工具,创建及资料表,填写 表名,程序就完全好了. 最后也说到,可能我们也会面对另外一些基础资料信息的维护,但是不是简单到只有代码 和名称,可能还有另 ...