iOS中常用的多线程操作有(
NSThread,
NSOperation
GCD
)
1.NSThread
线程的创建
1.
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(runAction:) object:nil];
thread.name = @"thread--1";
[thread start];
2.创建线程后自动启动线程
[NSThread detachNewThreadSelector:@selector(runAction:) toTarget:self withObject:nil];
PS:子线程中默认RunLoop是不启动的(主线程中的runloop是程序启动就运行)所以如果需要保持线程持续运行需要手动启动runloop
为了保证线程不死,我们考虑在子线程中加入RunLoop 但是由于RunLoop中没有没有源,就会自动退出RunLoop,所以我们要为子线程添加一个RunLoop,
并且为这个RunLoop添加源(保证RunLoop不退出) 在 runAction方法中加入如下代码:
//添加源
[[NSRunLoop currentRunLoop] addPort:[NSPort port] forMode:NSDefaultRunLoopMode];
// //启动RunLoop
[[NSRunLoop currentRunLoop] run];
2.NSOperation
使用子类
1.NSInvocationOperation:
同步
// 1.创建NSInvocationOperation对象
NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(runAction) object:nil]; // 2.调用start方法开始执行操作
//在没有使用NSOperationQueue、单独使用NSInvocationOperation的情况下, //NSInvocationOperation在主线程执行操作,并没有开启新线程。
[op start];
异步
// 1. 创建队列
NSOperationQueue *queue = [[NSOperationQueue alloc] init]; // 2.创建NSInvocationOperation对象
NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(runAsnysAction) object:nil]; [queue addOperation:op];
2.NSBlockOperation'
NSOperationQueue *queue = [[NSOperationQueue alloc] init]; NSBlockOperation *op0 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"addDependency0当前线程%@", [NSThread currentThread]);
}]; NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"addDependency1当前线程%@", [NSThread currentThread]);
}]; NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"addDependency2当前线程%@", [NSThread currentThread]);
}]; [op0 addDependency:op1]; // 添加依赖 这里等op1 op2执行完后再执行op0
[op0 addDependency:op2]; [queue addOperation:op1];
[queue addOperation:op2];
[queue addOperation:op0];
3.CGD
同步执行(sync):只能在当前线程中执行任务,不具备开启新线程的能力
异步执行(async):可以在新的线程中执行任务,具备开启新线程的能力
并发队列(Concurrent Dispatch Queue):可以让多个任务并发(同时)执行(自动开启多个线程同时执行任务),并发功能只有在异步(dispatch_async)函数下才有效
串行队列(Serial Dispatch Queue):让任务一个接着一个地执行(一个任务执行完毕后,再执行下一个任务)
在GCD中一个操作是多线程执行还是单线程执行取决于当前队列类型和执行方法,只有队列类型为并行队列并且使用异步方法执行时才能在多个线程中执行。
串行队列可以按顺序执行,并行队列的异步方法无法确定执行顺序。
UI界面的更新最好采用同步方法,其他操作采用异步方法。
GCD中多线程操作方法不需要使用@autoreleasepool,GCD会管理内存
如果在主线程中运用主队列同步,也就是把任务放到了主线程的队列中。
而同步对于任务是立刻执行的,那么当把第一个任务放进主队列时,它就会立马执行。
可是主线程现在正在处理 syncMain 方法,任务需要等 syncMain 执行完才能执行。
syncMain 执行到第一个任务的时候,又要等第一个任务执行完才能往下执行第二个和第三个任务。
这样 syncMain 方法和第一个任务就开始了互相等待,形成了死锁。
dispatch_queue_t mainQueue = dispatch_get_main_queue(); dispatch_sync(mainQueue, ^{
//do something
});
队列创建方法:
串行队列:
dispatch_queue_t queue= dispatch_queue_create("test.queue", DISPATCH_QUEUE_SERIAL);
并行队列:
Dispatch_queue_t queue= dispatch_queue_create("test.queue", DISPATCH_QUEUE_CONCURRENT)
dispatch_get_global_queue//全局并发队列
GCD定时器
// 获得队列
// dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_queue_t queue = dispatch_get_main_queue(); // 创建一个定时器(dispatch_source_t本质还是个OC对象)
self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue); // 何时开始执行第一个任务
// dispatch_time(DISPATCH_TIME_NOW, 3.0 * NSEC_PER_SEC) 比当前时间晚3秒 dispatch_time_t start = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC));
uint64_t interval = (uint64_t)(1.0 * NSEC_PER_SEC);
dispatch_source_set_timer(self.timer, start, interval, 0); // 设置回调
dispatch_source_set_event_handler(self.timer, ^{
NSLog(@"------------%@", [NSThread currentThread]);
count++; if (count == 10) {
// 取消定时器
dispatch_cancel(self.timer);
self.timer = nil;
count = 0;
}
}); // 启动定时器
dispatch_resume(self.timer);
dispatch_group_t:
// 创建一个队列组
dispatch_group_t group = dispatch_group_create(); dispatch_group_async(group, queue, ^{
//do something 1 });
dispatch_group_async(group, queue, ^{
//do something 2 });
dispatch_group_notify(group, queue, ^{
//当1和2都执行完后,合并执行 });
dispatch_barrier_async:
dispatch_barrier_async函数的作用与barrier的意思相同,在进程管理中起到一个栅栏的作用,它等待所有位于barrier函数之前的操作执行完毕后执行,并且在barrier函数执行之后,barrier函数之后的操作才会得到执行,该函数需要同dispatch_queue_create函数生成的concurrent Dispatch Queue队列一起使用
dispatch_queue_t queue = dispatch_queue_create("my-queue", DISPATCH_QUEUE_CONCURRENT); dispatch_async(queue, ^{ //1
}); dispatch_sync(queue, ^{
//2 }); dispatch_barrier_async(queue, ^(){
//当1,2执行完后才会执行此block
}); //等dispatch_barrier_async执行完再执行 dispatch_async(queue, ^{
、 }); dispatch_sync(queue, ^{ });
iOS 中多线程的简单使用的更多相关文章
-
iOS中多线程知识总结(一)
这一段开发中一直在处理iOS多线程的问题,但是感觉知识太散了,所以就把iOS中多线程的知识点总结了一下. 1.基本概念 1)什么是进程?进程的特性是什么? 进程是指在系统中正在运行的一个应用程序. ...
-
iOS中多线程原理与runloop介绍
一.线程概述 有些程序是一条直线,起点到终点:有些程序是一个圆,不断循环,直到将它切断.直线的如简单的Hello World,运行打印完,它的生命周期便结束了,像昙花一现那样:圆如操作系统,一直运行直 ...
-
转载 -- iOS中SDK的简单封装与使用
一.功能总述 在博客开始的第一部分,我们先来看一下我们最终要实现的效果.下图中所表述的就是我们今天博客中要做的事情,下方的App One和App Two都植入了我们将要封装的LoginSDK, 两个A ...
-
iOS中动画的简单使用
iOS中的动画右两大类1.UIView的视图动画2.Layer的动画 UIView的动画也是基于Layer的动画动画的代码格式都很固定 1.UIView动画 一般方式[UIView beginAnim ...
-
IOS中多线程的总结
首先要知道线程和进程的区别.一个系统上运行的每一个应用程序都是一个线程.而进程中要执行的任务都是在线程上来实现的,所以说线程是进程的最小执行单元. 进程最少要有一个线程.多线程,顾名思义就是多条线程. ...
-
C#中多线程的简单应用
下面是C#中使用多线程的一个简单用法介绍: //主线程: Thread thread = new Thread(new ThreadStart(ReadExportData));//创建分支线程thr ...
-
在iOS中实现一个简单的画板App
在这个随笔中,我们要为iPhone实现一个简单的画板App. 首先需要指出的是,这个demo中使用QuarzCore进行绘画,而不是OpenGL.这两个都可以实现类似的功能,区别是OpenGL更快,但 ...
-
iOS中多线程的实现方案
什么是主线程? 一个iOS程序运行后,默认会开启一条线程,称为“主线程”或“UI线程” 主线程的主要作用 1.显示/刷新UI界面 2.处理UI事件(比如点击事件,滚动事件,拖拽事件) 主线程的使用注意 ...
-
iOS中多线程知识总结(二)
1.GCD GCD全称是Grand Central Dispatch,译为"强大的中枢管理器" 1)什么是任务?什么是队列? 任务和队列是GCD的核心. 任务: 执行什么操作 队列 ...
随机推荐
-
[原创]Windows Server 2003 物理机转换为VMware虚拟机出现VSS错误的处理
一台Windows Server 2003 物理机需要转换为VMware虚拟机,工具为Vmware vCenter Converter Standalone 6.0,转换开始就出现错误“FAILED: ...
-
.net单元测试初探
写在前面 组里接手了一个在运行的票台系统,包括收银,客户体验,店内商超等子系统,要求将服务端进行云端化,以应对分店的增多和决策层对于数据的需要,而随着时间的退役和各种收费策略的改变,促销活动的展开等, ...
-
LINQ语法记录
static void Main(string[] args) { List<Person> persons = new List<Person>(); persons.Add ...
-
POJ 3740
http://poj.org/problem?id=3740 这是一道搜索+回溯的题目,也是我第一次接触到回溯. 题意就是找一些行,这些行可以使每一列都只存在一个1. 深搜加回溯: memory:11 ...
-
[C++] memset 和sizeof 的使用注意
因为使用C++写小题目时经常需要清除数组,这里记录下Memset函数的sizeof运算符的使用注意. memset的特点是:将给定地址后连续的内存(包括给定地址),逐个byte初始化为参数中指明的值. ...
-
重新想象 Windows 8 Store Apps (47) - 多线程之线程同步: Semaphore, CountdownEvent, Barrier, ManualResetEvent, AutoResetEvent
[源码下载] 重新想象 Windows 8 Store Apps (47) - 多线程之线程同步: Semaphore, CountdownEvent, Barrier, ManualResetEve ...
-
CSS3中颜色线性渐变实战
css3线性渐变可以设置3个参数值:方向.起始颜色.结束颜色.最简单的模式只需要定义起始颜色和结束颜色,起点.终点和方向默认自元素的顶部到底部.下面举例说明: CSS Code复制内容到剪贴板 .te ...
-
Android的主要组件
(一)Activity(活动) 作用:提供可视化用户界面 只能通过setContentView(View)来显示指定组件 View组件是所有UI控件.容器控件的基类,View组件就是android应用 ...
-
【Linux高频命令专题(12)】touch.md
概述 一般在使用make的时候可能会用到,用来修改文件时间,或者新建一个不存在的文件. 命令格式 touch [选项]... 文件... 命令参数 -a 或--time=atime或--time=ac ...
-
互联网金融爬虫怎么写-第一课 p2p网贷爬虫(XPath入门)
版权声明:本文为博主原创文章,未经博主允许不得转载. 相关教程: 手把手教你写电商爬虫-第一课 找个软柿子捏捏 手把手教你写电商爬虫-第二课 实战尚妆网分页商品采集爬虫 手把手教你写电商爬虫-第三课 ...