主线程的作用 (在主线程中才能设置)

显示/刷新UI界面

处理UI事件(比如点击事件、滚动事件、拖拽事件);

主线程的使用注意

别将比较耗时的操作放到主线程中。

耗时操作会卡住主线程。影响体验。

[NSThread currentThread]获得当前线程。

打印线程。num属性显示有多少条线程。

将耗时操作放在子线程中(后台线程,非主线程);

多线程好处在哪?

在用户点击按钮那一刻就有反应

能同时处理耗时操作和用UI控件的事件。

多线程技术:

1,pthread    一套通用的多线程API(几乎不用)

适用于Unix\Linux\Windows等系统

跨平台\可移植

使用难度大。

需要程序员来管理线程的生命周期。

创建一个线程用

pthread_create(&pthread_t,NULL,(void *)(*)(void *),NULL);即可

2,NSThread  使用OC,(程序员管理)

使用更加面向对象

简单易用,可直接操作线程对象

创建一个线程用 [NSThread alloc] init……

[self start] 开启;

selector(mainThread) 返回主线程;

selector(isMainThread) 是否是主线程;

selector (currentThread); 判断当前线程;

可以设置线程优先级,

优先级越高,CUP的占有率越高。

线程有name属性,可以设置名字。

创建线程第2种方式:

[NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:nil];

分离一条线程,没有返回值。

创建线程第3种方式。

[self performSelectorInBackground:@selector(run:) withObject:@"abc参数"];

每一个时刻只有一个线程在执行。

[thread start]后进入一个可调度线程池(有机会被调度。状态为就绪或运行);

start

new  ----》 就绪  -----》运行

《------

调用了sleep方法或等待同步锁 后就进入  阻塞状态(清出线程池)  条件满足后又回到调度池。

调用stop 线程进入的是dead 死亡状态。再也没有了。

+(void)sleepUntilDate:(NSDate *)date;

+(void) sleepForTimeInterval:(NSTimeInterval)ti;

线程运行完之后就会死亡, 不能能再次调用。

[thread exit]线程退出。

3,GCD   C

旨在替代NSThread等线程技术

充分利用设备的多核。(自动)

不用管理线程。

GCD有2个核心概念

任务:执行什么样的操作。

队列:用来存放任务。

GCD的使用就2个步骤。

定制任务

确认想做的事情。

将任务添加到队列中

GCD会自动将队列中的任务取出,放到对应的线程中执行。

任务取出遵循队列的FIFO原则,先进先出。后进后出

调用libdispach库才行

都是懿dispatch开头。

1,用同步的方式来执行任务。(有顺序执行)

dispatch_sync(queue,block);同步执行

queue:队列

block:任务

2,用异步的方式执行任务(在另一条线程中执行)

dispatch_async(queue,block);

GCD队列分2大类;

并发队列;

可以让任务同时执行。

串行队列

用函数给队列赋值任务;

队列分为并行和串行。

函数分为同步和异步。

异步函数加并行队列  == 开一条子线程。

同步:在当前线程中执行任务,不具备开启新线程能力

异步:在新的线程中执行任务,具备开启新线程的能力。

并发和串行决定了任务的执行方式。

并发:多个任务并发执行。  调用dispatch_queue_t queue = dispatch_get_global_queue(优先级,随意值);

添加任务到队列中,执行任务。

串行:一个任务执行完毕后,再执行下一个任务。

serial 英文,连续,串行的意思。。

dispatch_queue_t queue = dispatch_queue_create("com.itheima,queue",队列的类型);

队列名称在调试的时候可以看的到代码在哪个队列里面执行。

调用async函数会开启一个线程,但是如果函数的队列是串行的就不会开更多了。每加一个并行队列开启线程数会加1.

调用sync函数不会开线程。并行和串行队列都一样

MRC里面释放用dispatch_release(queue);

ARC里面不能用,会自动释放。

即使在ARC中

凡是函数名中带有create\copy\new\retain等字眼返回值的,都需要在不使用这个数据的时候进行release(有的话都写一下,报错就不写了)

GCD数据类型则不用,release。

CF(Core foundation)的数据类型在ARC环境下还是得需要再做release;

系统自带的用get ,自己创的用create 。(苹果规范);

主线程队列是不会开新线程的。

别在主线程中用同步函数添加主队列,会形成相互等待,死锁。

用异步函数可以(异步可以延缓执行,同步要马上执行)。

同步会在当前进程中执行,会停下来。异步会自己开一个线程。与当前线程并发执行,(只要队列不是主队列)

iOS常见的延时执行有2种方式;

1,[self performSelector:@selector(run)  withObject:nil afterDelay:2.0];

2秒之后调用run方法;

2,GCD方式

dispatch_after();//有个队列参数,表示多少秒后在哪个线程中执行。

//1.声明在哪个队列

dispatch_queue_t queue = dispatch_get_main_queue();

// 2.计算任务执行的时间

dispatch_time_t when = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5.0 * NSEC_PER_SEC));

// 3.会在when这个时间点, 执行queue中的任务

dispatch_after(when, queue, ^{        //会另外声明一个队列。

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

});

需要整个程序执行过程中只能打印一次时。

static dispatch_once_t onceToken;

可以用 dispatch_once(&onceToken,^{

NSLog(@"--------touchesBegin");

});

队列组,:

有这么一种需求。

等2个线程都执行完之后再到主线程中执行操作。

就可以用队列组把2个线程封装。执行队列组。

创建group//比串行执行要快很多。。。

dispatch_group_t group = dispatch_group_create();

创建队列

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

把任务和队列放到异步组函数中

*/

dispatch_group_async(group, queue, ^{

for (int i=0; i<100; i++) {

NSLog(@"执行线程一:%d",i);

}

});

dispatch_group_async(group, queue, ^{

for (int i=0; i<100; i++) {

NSLog(@"执行线程二:%d",i);

}

});

//线程组执行完成后执行:(重点,没有它,要组也没啥用了)

dispatch_group_notify(group, queue, ^{

NSLog(@"线程组执行完成");

});

//下面是重复执行:10代表重复执行次数。中间是执行队列。index是第几次执行;(注意执行是并发(这是与for循环的区别));

dispatch_apply(10, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(size_t index) {

//index表示是第几次执行

NSLog(@"执行第%zu次",index);

});

栅栏barrier ,用来将线程分开,执行完上面的线程到执行它再到执行后面的线程;(有队列queue关键字,所以就是把queue队列的隔开,其它队列可不行,中间执行)

dispatch_barrier_async(queue, ^{

NSLog(@"barrier");

});

4,NSOperation  OC

基于GCD

比GCD多了一些简单实用的功能

使用更加面向对带的用get ,自己创的用create 。(苹果规范);

, 配合使用NSOperation NSOperationQueue也能实现多线程编程

,NSOperation和NSOperationQueue 实现多线程的具体步骤

先将需要执行的操作封装到一个NSOperation 对象中。

然后将NSOperation对象添加到NSOperationQueue中

系统会自动将NSOperationQueue中的NSOperation取出来

将取出的NSOperation封装的操作放到一条新线程中执行。

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

使用NSOperation子类的方式有3种。

NSInvocationOperation

NSBlockOperation

自定义的子类继承NSOperation,实现内部相应的方法。

NSInvocationOperation

创建操作对象,封装要执行的任务。

NSInvocationOperation * operation = [  alloc]  initwithTarget……   任务是方法;

可以[operation start]调用,但是这样是会在当前线程中调用,并无啥用,还是得放到方法中去;

NSBlockOperation

使用类方法来声明

NSBlockOperation * operation = [NSBlockOperation blockOperationWithBlock^{   }];   任务是block ,NSBlockOperation 是block的封装

也可以  直接用start 调用,但也无啥用。

有方法:  [operation addExecutionBlock:^{

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

}];

只要operation封装的任务大于1,就会异步执行。

调用了addExecutionBlock 的话 operation的任务就有多个。   用start是会多线程执行的。

-(void) invocationOperation

{

}

NSOperatinQueue * queue =[ [NSOperationQueue alloc] init];

[queue addOperation:operation1];

[queue addOperation:operation2];//这样直接就会是异步执行。   (并发有着不确定性。但是概率是会有的)

队列可以设置 最大并发数,  queue.maxConcurrentOperationCount = 1;  表示在这个队列中最多同时执行的并发任务数为1;

(不要设置太多,不然可能会卡, 2-3就好,5以内,不然UI会卡);

- (void) cancelAllOperations; 队列的全部线程都停掉

也可以调用NSOperation 的-(void)cancel 方法取消单个操作。

-(void)setSuspended:(BOOL)b;//YES 代表暂停队列。

//(一个比较好的地方是 : cancel代表取消的意思,suspended,表示已经挂起,这些英文记住了用来命名挺好的,看看别人的过去时都是加ed的,就是这么强,所以语法不好的话,多关注ios的命名规则时很好的);

当下载时,同时开启多条子线程,当用户操作UI时会发生卡顿现象,那么我们就可以在用户滚动时挂起队列。不操作时就继续队列/

下载时同时开启多条线程下载会比较快。

有个有趣的地方是 NSOperation 居然也有一个队列优先级, 我了个去, 不愧是GCD的封装啊 ,就是那么强大。

还可以设置依赖。来保证执行的顺序;

[operationB addDependency: operationA]; B依赖A  那么B只能在A之后执行。(灵活应用可以做很多事情。)

A-》B    B -》C   C—》A

小心相互依赖问题。

可以在不同的queue的NSOperation之间创建依赖关系。但是不能相互依赖。

操作的监听。

operation.completionBlock = ^{

//下载完图片后想做的事情。

};

自定义Operation(继承自Operation)

要在operation里面实现  -(void)main{}方法

多线程安全隐患:1,一块资源可能会被多个线程共享,也就是多个线程可能会访问同一个资源

比如说多个线程访问同一个对象、同一个变量、同一个文件。

使用线程锁来解决,同一时间只能有一个线程访问。

IOS线程的一些总结的更多相关文章

  1. IOS 线程处理 子线程

    IOS 线程处理 子线程的启动与结束 技术交流新QQ群:414971585   IOS中,如果要在主线程中启动一个子线程,可以又两种方法: [NSThread detachNewThreadSelec ...

  2. iOS线程之——NSCondition

    多线程在各种编程语言中都是难点,很多语言中实现起来很麻烦,objective-c虽然源于c,但其多线程编程却相当简单,可以与java相媲美.这篇文章主要从线程创建与启动.线程的同步与锁.线程的交互.线 ...

  3. iOS 线程操作库 PromiseKit

    iOS 线程操作库 PromiseKit 官网:http://promisekit.org/ github:https://github.com/mxcl/PromiseKit/tree/master ...

  4. ios线程和GCD

    1.什么是进程? 进程是指在系统中正在运行的一个应用程序.比如同时打开QQ.Xcode,系统就会分别启动2个进程.截图 2.什么是线程? 1).一个进程要想执行任务,必须得有线程(每一个进程至少要有一 ...

  5. iOS - 线程管理

    iOS开发多线程篇—GCD的常见用法 一.延迟执行 1.介绍 iOS常见的延时执行有2种方式 (1)调用NSObject的方法 [self performSelector:@selector(run) ...

  6. iOS 线程锁同步机制

    转载自 http://yulingtianxia.com/blog/2015/11/01/More-than-you-want-to-know-about-synchronized/ 如果你已经使用 ...

  7. IOS线程操作(3)

    采用CGD更有效的比前两个(它被认为是如此,有兴趣的同学可以去试试). 这是推荐的方式来使用苹果的比较. GCD它是Grand Central Dispatch缩写,这是一组并行编程C介面. GCD是 ...

  8. ios线程和GCD和队列同步异步的关系

    1.什么是进程? 进程是指在系统中正在运行的一个应用程序.比如同时打开QQ.Xcode,系统就会分别启动2个进程.截图 2.什么是线程? 1).一个进程要想执行任务,必须得有线程(每一个进程至少要有一 ...

  9. iOS 线程安全--锁

    一,前言 线程安全是iOS开发中避免了的话题,随着多线程的使用,对于资源的竞争以及数据的操作都可能存在风险,所以有必要在操作时保证线程安全. 二,为什么要使用锁? 由于一个进程中不可避免的存在多线程, ...

随机推荐

  1. Hibernate5.2之原生SQL查询

    Hibernate5.2之原生SQL查询 一. 介绍  在上一篇博客中笔者通过代码的形式给各位读者介绍了Hibernate中最重要的检索方式--HQL查询.在本博文中笔者将向各位读者介绍Hiberna ...

  2. jquery判断复选框checkbox是否被选中

    jquery判断复选框checkbox是否被选中 使用is方法 //如果选中返回true //如果未选中返回false .is(':checked');

  3. 每天一个 Linux 命令(6):rmdir 命令

    今天学习一下linux中命令: rmdir命令.rmdir是常用的命令,该命令的功能是删除空目录,一个目录被删除之前必须是空的.(注意,rm – r dir命令可代替rmdir,但是有很大危险性.)删 ...

  4. [IIS]IIS扫盲(四)

    IIS简易安装 义哥门户网   IIS(Internet Information Server,互联网信息服务)是一种Web(网页)服务组件,其中包括Web服务器.FTP服务器.NNTP服务器和SMT ...

  5. Dapper ORM 用法—Net下无敌的ORM

    假如你喜欢原生的Sql语句,又喜欢ORM的简单,那你一定会喜欢上Dapper这款ROM.点击下载Dapper的优势:1,Dapper是一个轻型的ORM类.代码就一个SqlMapper.cs文件,编译后 ...

  6. 40. Interleaving String

    Interleaving String Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2. Fo ...

  7. JS语法(二)

    JS变量 var 变量名 = 变量值://自己会判断什么类型 一个好的编程习惯是,在代码开始处,统一对需要的变量进行声明. var name = “xiaosan”, age = 22, addres ...

  8. Spring:No bean named 'beanScope' is defined

    初学Spring,“No bean named 'beanScope' is defined”这个问题困扰了我好几个小时,查资料无果后,重写好几遍代码后发现问题居然是配置文件不能放在包里...要放在s ...

  9. openldap权限sudo

    http://pig.made-it.com/ldap-sudoers.html https://www.lisenet.com/2015/convert-openldap-schema-to-ldi ...

  10. php 连接mongodb 增查改删操作

    查询 <?php $m=new MongoClient('mongodb://admin:admin@localhost:27017/admin'); $db=$m->hndb; $cc= ...