什么是主线程?

一个iOS程序运行后,默认会开启一条线程,称为“主线程”或“UI线程”

主线程的主要作用

1.显示/刷新UI界面

2.处理UI事件(比如点击事件,滚动事件,拖拽事件)

主线程的使用注意

1.别将比较耗时的操作放在主线程中

2.耗时操作会卡在主线程中,严重影响UI的流畅程度

如图,将耗时操作放在主线程中,任务会按照串行顺序执行,在第五秒点击按钮之后,界面会卡住5秒

因为耗时操作还没有执行完,不能立即响应按钮的点击

1.pthread的使用

void *run(void *parme) {

    NSLog(@"%@",[NSThread currentThread]);

    for (int i = ; i < ; i++) {
NSLog(@"%d",i);
}
return NULL; } - (IBAction)btnClick:(id)sender { pthread_t thread;
pthread_create(&thread, NULL, run, NULL); }

2.NSThread的使用

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
[self createThread3];
} //第一种创建方法
- (void)createThread1 {
//需要几个线程就alloc几个
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run:) object:@"第一种"];
thread.name = @"one_thread";
[thread start];
}
//第二种创建方法
- (void)createThread2 { [NSThread detachNewThreadSelector:@selector(run:) toTarget:self withObject:@"第二种"];
} //第三种创建方法
- (void)createThread3 { [self performSelectorInBackground:@selector(run:) withObject:@"第三种"];
} - (void)run:(NSString *)param {
NSLog(@"______%@_____%@",param,[NSThread currentThread]);
}

3.GCD的使用

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
[self syncMain];
} /**
同步函数+主队列
*/
- (void)syncMain {
dispatch_queue_t queue = dispatch_get_main_queue(); NSLog(@"syncMain ---- begin");
//将任务加入到队列
dispatch_sync(queue, ^{
NSLog(@"1----%@",[NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"2----%@",[NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"3----%@",[NSThread currentThread]);
}); NSLog(@"syncMain ---- end");
} /**
异步函数+主队列
*/
- (void)asyncMain { //异步函数用在主队列上就不会开线程了
//获得串行队列
dispatch_queue_t queue = dispatch_get_main_queue(); //将任务加入到队列
dispatch_async(queue, ^{
NSLog(@"1----%@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"2----%@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"3----%@",[NSThread currentThread]);
});
} /**
同步函数+串行队列:不会开启新的线程,在当前线程执行任务
*/
- (void)syncSerial {
//创建串行队列
dispatch_queue_t queue = dispatch_queue_create("com.520.queue", DISPATCH_QUEUE_SERIAL); //将任务加入到队列
dispatch_sync(queue, ^{
NSLog(@"1----%@",[NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"2----%@",[NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"3----%@",[NSThread currentThread]);
});
} /**
异步函数+串行队列:会开启新的线程,但是任务是串行的,执行完一个任务,再执行下一个任务
*/
- (void)asyncSerial {
//创建串行队列
dispatch_queue_t queue = dispatch_queue_create("com.520.queue", DISPATCH_QUEUE_SERIAL); //将任务加入到队列
dispatch_async(queue, ^{
NSLog(@"1----%@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"2----%@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"3----%@",[NSThread currentThread]);
});
} /**
同步函数+并发队列:不会开启线程,不能
*/
- (void)syncConcurrent {
//获得全局的并发队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, ); //将任务添加到队列
dispatch_async(queue, ^{
NSLog(@"1----%@",[NSThread currentThread]);
}); dispatch_async(queue, ^{
NSLog(@"1----%@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"1----%@",[NSThread currentThread]);
});
} /**
异步函数+并发队列:可以同时开启多条线程
*/
- (void)asycConcurrent {
//创建一个队列
//第一个参数是标签等同于名字
//第二个参数传串行还是并行
// dispatch_queue_t queue = dispatch_queue_create("img.download", DISPATCH_QUEUE_CONCURRENT); //获得全局的并发队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, ); //将任务添加到队列
dispatch_async(queue, ^{
for (int i = ; i < ; i++) {
NSLog(@"1----%@",[NSThread currentThread]);
}
}); //将任务添加到队列
dispatch_async(queue, ^{
for (int i = ; i < ; i++) {
NSLog(@"2----%@",[NSThread currentThread]);
}
}); //将任务添加到队列
dispatch_async(queue, ^{
for (int i = ; i < ; i++) {
NSLog(@"3----%@",[NSThread currentThread]);
}
});
}

在使用GCD时,主要分为两步

1.定制任务

2.将任务添加到队列

这里还需要区分下同步,异步,并行,串行

同步异步:影响是否开启新的线程

并行串行:影响任务的执行方式

4.NSOperation的使用

NSOperation是抽象类,并不具备封装操作,必须使用它的子类

使用NSOperation子类的方式有三种

1.NSInvocationOperation

2.NSBlockOperation

3.自定义子类继承NSOperation,实现内部响应的方法

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {

    //创建队列
NSOperationQueue *queue = [[NSOperationQueue alloc] init]; //创建任务1(invocationOperation方法)
NSInvocationOperation *op1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(download1) object:nil]; //创建任务2(blockOperation方法)
NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"download2----%@",[NSThread currentThread]);
}]; [op2 addExecutionBlock:^{
NSLog(@"download3----%@",[NSThread currentThread]);
}]; //创建任务3(自定义方法)
DDZOperation *op3 = [[DDZOperation alloc] init]; //添加任务到队列中
[queue addOperation:op1];//内部自动调start方法
[queue addOperation:op2];
[queue addOperation:op3];
} - (void)download1 {
NSLog(@"download1----%@",[NSThread currentThread]);
}

补充在自定义的DDZOperation中只有实现main方法才会开启线程处理任务

@implementation DDZOperation

- (void)main {
NSLog(@"自定义-----%@",[NSThread currentThread]);
}

iOS中多线程的实现方案的更多相关文章

  1. iOS中多线程知识总结(一)

    这一段开发中一直在处理iOS多线程的问题,但是感觉知识太散了,所以就把iOS中多线程的知识点总结了一下. 1.基本概念 1)什么是进程?进程的特性是什么? 进程是指在系统中正在运行的一个应用程序.   ...

  2. iOS中多线程原理与runloop介绍

    一.线程概述 有些程序是一条直线,起点到终点:有些程序是一个圆,不断循环,直到将它切断.直线的如简单的Hello World,运行打印完,它的生命周期便结束了,像昙花一现那样:圆如操作系统,一直运行直 ...

  3. iOS 中多线程的简单使用

    iOS中常用的多线程操作有( NSThread, NSOperation GCD ) 为了能更直观的展现多线程操作在SB中做如下的界面布局: 当点击下载的时候从网络上下载图片: - (void)loa ...

  4. IOS中多线程的总结

    首先要知道线程和进程的区别.一个系统上运行的每一个应用程序都是一个线程.而进程中要执行的任务都是在线程上来实现的,所以说线程是进程的最小执行单元. 进程最少要有一个线程.多线程,顾名思义就是多条线程. ...

  5. iOS中多线程常用的知识点

        1.pThread 跨平台的多线程技术 , 是IEEE制定的POSIX 表示可移植性操作系统接口的多线程计数,UNIX内核平台 Unix,Linux,Mac(小红帽) (windows上有可移 ...

  6. C# 中 多线程同步退出方案 CancellationTokenSource

    C# 中提供多线程同步退出机制,详参对象: CancellationTokenSource CancellationTokenSource 中暂未提供复位操作,因此当调用Cancle 之后,若再次调用 ...

  7. iOS中多线程知识总结(二)

    1.GCD GCD全称是Grand Central Dispatch,译为"强大的中枢管理器" 1)什么是任务?什么是队列? 任务和队列是GCD的核心. 任务: 执行什么操作 队列 ...

  8. ios中多线程GCD NSOperation NSThread 相关的操作解析

    //1.GCD 继承自C语言 优点 简单方便 //开启一个子线程处理耗时的操作 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIO ...

  9. OS X 和iOS 中的多线程技术(上)

    OS X 和iOS 中的多线程技术(上) 本文梳理了OS X 和iOS 系统中提供的多线程技术.并且对这些技术的使用给出了一些实用的建议. 多线程的目的:通过并发执行提高 CPU 的使用效率,进而提供 ...

随机推荐

  1. 高性能Javascript--高效的数据访问

    接上一篇,希望能写一个高性能Javascript专题. 第一篇:高性能Javascript--脚本的无阻塞加载策略. 参考摘录<高性能Javascript>. 经典计算机科学的一个问题是, ...

  2. EMC与地之重新认识地

    记得在Mark的培训中,他手上拿了一个无线鼠标,然后问了一个很有意思的问题:“这个无线鼠标的地在哪里?同样,我们的手机没有和任何大地有接 触,那么这个地又在哪里呢?”这个问题确实很有意思,也确实让人很 ...

  3. hibernate学习笔记之二 基本环境搭建

    1.创建一个普通的java项目 2.加入Hibernate所有的jar包 3.建立包名com.bjpowernode.hibernate 4.建立实体类User.java package com.bj ...

  4. Quartz.net开源作业调度框架使用详解

    前言 quartz.net作业调度框架是伟大组织OpenSymphony开发的quartz scheduler项目的.net延伸移植版本.支持 cron-like表达式,集群,数据库.功能性能强大更不 ...

  5. JavaScript的闭包

    1. 什么是闭包 通俗地讲,JavaScript 中每个的函数都是一个闭包,但通常意义上嵌套的函数更能够体现出闭包的特性,请看下面这个例子: var generateClosure = functio ...

  6. C# windows服务制作(包括安装及卸载)

    开篇语 因工作内容需要做一个windows服务,此前并没有相关经验,所以做了一个demo来跑跑这个梗(高手跳过,需要的来踩)- 效果如下:打开服务,可以找到我们新增的一个windows服务,这个dem ...

  7. SpringMVC中定时任务配置

    在项目中使用定时任务是常有的事,比如每天定时进行数据同步或者备份等等. 以前在从事C语言开发的时候,定时任务都是通过写个shell脚本,然后添加到linux定时任务中进行调度的. 现在使用Spring ...

  8. 如何重置硬盘遭到“损坏”的Linux系统root用户密码

    传统印象下Linux是非常坚不可摧的,具有千年不更新,万年不重启的美名.而随着虚拟化的推进,很多跑在虚拟化上的Linux由于先前基础架构的脆弱,变得适应性“越来越不好”,体现在IP存储如果出现节点故障 ...

  9. SharePoint2013 Set a custom application page as site welcome page

    本文主要介绍如何添加一个custom application page as site welcome page 1.首先创建一个sharepoint 2013 empty solution, add ...

  10. 【NLP】条件随机场知识扩展延伸(五)

    条件随机场知识扩展延伸 作者:白宁超 2016年8月3日19:47:55 [摘要]:条件随机场用于序列标注,数据分割等自然语言处理中,表现出很好的效果.在中文分词.中文人名识别和歧义消解等任务中都有应 ...