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

显示/刷新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. 封装实现一个自己的tabbar

    实现效果:

  2. FileUploadInterceptor拦截器的笔记

    当请求表单中包含一个文件file,FileUploadInterception拦截器会自动应用于这个文件. 表单: <s:form namespace="/xxx" acti ...

  3. php include require

    includ和require都是把其他页面加载当前页面,不过不同的是,require如果没有找到,或者所包含的页面里面有错误就不会往下执行了 <?php include 'form.php'; ...

  4. spring component-scan filter

    (参考的Spring version : 4.1.6.RELEASE) 我们通常会使用component-scan来进行bean的加载,但是它里面的实现机制却是一知半解.根据原码来理解一下,可能会更加 ...

  5. EditText 自动格式化电话电话号码

    需要格式化的格式为:xxx xxxx xxxx 有两种方式:1.为监听当前输入的长度,当长度为第四位,九位的时候,在原内容上追加空格.(from stackOverFlow)2.每次输入后,格式化当前 ...

  6. Linux 11g rac PSU

    PSU补丁:p22191577_112040_Linux-x86-64.zipOPATCH工具:p6880880_112000_LINUX.zip 解压OPATCH工具 覆盖到/u01/11.2.0/ ...

  7. Spark Streaming、HDFS结合Spark JDBC External DataSouces处理案例

    场景:使用Spark Streaming接收HDFS上的文件数据与关系型数据库中的表进行相关的查询操作: 使用技术:Spark Streaming + Spark JDBC External Data ...

  8. Symfony2 资料篇

    http://www.chrisyue.com/symfony2-in-action-day-1.html 由于Symfony2现在还没有很完善的中文文档,所以不想看文档的同学可以直接进行点击上面的链 ...

  9. 【转】web测试总结

    1.字符型输入框: (1)字符型输入框:英文全角.英文半角.数字.空或者空格.特殊字符“~!@#¥%……&*?[]{}”特别要注意单引号和&符号.禁止直接输入特殊字符时,使用“粘贴.拷 ...

  10. 【T电商2】ftp服务器搭建

    一.为什么需要ftp? 分布式环境一般都有一个专门的图片服务器存放图片.我们使用虚拟机搭建一个专门的服务器来存放图片.在此服务器上安装一个nginx来提供http服务,安装一个ftp服务器来提供图片上 ...