iOS开发中的多线程

一个iOS程序,默认开启1条线程--主线程orUI线程
主线程主要作用:
        显示/刷新UI界面
        处理UI事件(点击、滚动、拖拽事件等)
主线程使用注意:
        别将耗时操作放在主线程
        
耗时操作应放在子线程(后台线程or非主线程)

iOS中多线程实现方案

 
 

1.pthread -- POSIX Thread    iPhone2.0

创建子线程:pthread_create
 

2. NSThread -- 一个NSThread对象代表一条线程

创建和启动线程
    [[NSThread alloc] initWithTarget:self selector:@selector(run:) object:nil];
    [thread start];
 
主线程相关方法
    + (NSThread *)mainThread; //获得主线程
    - (BOOL)isMainThread; //判断是否为主线程
    + (BOOL)isMainThread;
 
其他用法
其他创建线程方式
    创建线程后自动启动
        [NSThread detachNewThreadSelector:toTarget:withObject:];
    隐式创建线程后自动启动
        [self performSelectorInBackground:withObject:]; // NSObject的方法
 
线程状态
 阻塞(暂停)线程
  + (void)sleepUntilDate:
  + (void)sleepForTimeInterval:
强制停止线程
  + (void)exit   //进入死亡状态
  注意:一旦线程停止,就不能再次开启任务
 
线程同步
    互斥锁 -- 线程同步
    @synchronized(锁对象 eg: self){//加锁
        ....需要锁住的代码
        ....一份代码只能对应一把锁
    }//解锁
 
   
   
线程间通信
 
   

3.GCD -- Grand Central Dispatch "牛逼的中枢调度器"

任务和队列
    队列:用来存放任务
    GCD步骤:定制任务-->将任务添加到队列 (GCD自动取出队列中任务,放到对应线程执行)
    任务的取出遵从:FIFO原则
 
同步:在当前线程中执行(不具备开启新线程能力)
异步:在另一条线程中执行
 
---------------------------
全局并发队列:dispatch_get_global_queue
串行队列:
    1) dispatch_queue_create();   在MRC中调用dispatch_release(queue)
    2) 使用主队列(跟主线程相关联的队列) -- dispatch_get_main_queue
            主队列是GCD自带的特殊串行队列;
            放在主队列中的任务,都会放到主线程中执行
 
GCD其他用法
 
只执行一次
    dispatch_once
 
队列组
    

4. NSOperation

1> 基本使用

NSOperation和NSOperationQueue实现多线程
 
2>NSOperation(抽象类)子类:

》NSInvocationOperation
创建并启动操作对象:
[[NSInvocationOperation alloc]initWithTarget:selector:object];
[operation start]; //默认情况下不会创建新线程;除非放到队列中
 

》NSBlockOperation

[NSBlockOperation blockOperationWithBlock:];
[operation start];//默认情况下不会创建新线程;除非放到队列中
 
[operation addExecutionBlock:];//当operation中的操作个数>1就会开启新线程

》自定义子类
必须实现main方法,在main方法中实现具体操作
- (void)main
{
    ......
}

3> NSOperationQueue

[[NSOperationQueue alloc]init];
[queue addOperation:]; //自动执行操作,自动开启线程;默认是并发执行
[queue addOperationWithBlock:]
最大并发数设置
- (void)setMaxConcurrentOperationCount:(NSInteger)cnt;
一般2-3并发数,5以内
 
队列的取消、暂停、恢复
- (void)cancelAllOperations
- (void)setSuspended:BOOL // YES代表暂停,NO代表恢复
*设置依赖
[operationB addDependency:operationA]; // 操作B依赖于操作A

也可以在不同队列的操作间设置依赖
注意:不能相互依赖
 
操作的监听
operation.completionBlock=^{};
 

RunLoop

不能显示的创建管理runloop,每个thread自己就会有一个runloop,在当前线程调用 currentRunLoop方法就能得到线程对应的runloop

作用

。使程序一直运行并接收用户输入

。决定程序在何时处理那些Event

。调用解耦(--消息队列)

。节省CPU时间

RunLoops in Cocoa

Cocoa中跟RunLoop有关的类

NSTimer,UIEvent,Autorelease,NSDelayedPerforming,NSThreadPerformAddition

CADisplayLink,CATransition,CAAnimation,dispatch_get_main_queue(), NSURLConnnection.....

调用堆栈中

Xcode调试时调用堆栈中以__CFRunLoopxxxxxx的函数

RunLoop机制

》CFRunLoopTimer

RunLoopTimer的封装

+ (NSTimer *)timerWithTimeInterval: invocation: repeats:

+ (NSTimer *)scheduledTimerWithInterval: invocation: repeats:

- (void)performSelector: withObject: afterDelay: inModes:

+ (CADisplayLink *)dispalyLinkWithTarget: selector:

- (void)addToRunLoop: forMode:

》CFRunLoopSource

Source是RunLoop的数据源抽象类(protocol)

RunLoop定义了两个Version的Source:

  1. Source0:处理App内部事件、App自己负责管理(触发)如UIEvent、CFSocket

  2. Source1:由RunLoop和内核管理、Mach port驱动,如CFMachPort,CFMessagePort

》CFRunLoopObserver

》CFRunLoopMode

。RunLoop在同一时间段只能且必须在一种特定Mode下Run

。更换Mode时,需要停止当前loop,然后重启新loop

。Mode是iOS App滑动顺畅的关键

NSDefalutRunLoopMode

  默认状态、空闲状态

UITrackingRunLoopMode

  滑动ScrollView时

UIInitializationRunLoopMode

  私有,App启动时

NSRunLoopCommonModes

  以上一个或几个的组合(可以自己定义组合)

ScrollView滑动时RunLoopMode的切换:NSDefalutRunLoopMode -开始滑动-> UITrackingRunLoopMode -停止滑动-> NSDefalutRunLoopMode

》GCD中dispatch到main queue的block被分发到main RunLoop执行,dispatch_after同理

》RunLoop的挂起和唤醒

》AFNetworking中创建了一个单例network 线程,用RunLoop让这个线程常驻(不会执行完某次网络操作就杀掉)

这样子是否只开了一个网络请求子线程?

多线程与RunLoop的更多相关文章

  1. iOS开发——多线程篇——RunLoop

    一.简介 1.什么是RunLoop从字面意思看运行循环跑圈 基本作用保持程序的持续运行处理App中的各种事件(比如触摸事件.定时器事件.Selector事件)节省CPU资源,提高程序性能:该做事时做事 ...

  2. 多线程(RunLoop)

    1.RunLoop的概念及作用 2.RunLoop的使用 3.RunLoop的相关类 4.RunLoop的工作原理 5.小结 6.思考 什么是RunLoop? 从字面意思上是一直循环跑,事实上就是一个 ...

  3. RunLoop 总结:RunLoop的应用场景(二)

    上一篇讲了使用RunLoop保证子线程的长时间存活,而不是执行完任务后就立刻销毁的应用场景.这一篇就讲述一下RunLoop如何保证NSTimer在视图滑动时,依然能正常运转. 参考资料 好的书籍都是值 ...

  4. QF——网络之知识碎片

    1.URL中文问题: URL不支持中文.若出现中文,需要对URL进行utf-8编码. NSString *urlString = [kULRSTRING stringByAddingPercentEs ...

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

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

  6. iOS 多线程:『RunLoop』详尽总结

    1. RunLoop 简介 1.1 什么是 RunLoop? 可以理解为字面意思:Run 表示运行,Loop 表示循环.结合在一起就是运行的循环的意思.哈哈,我更愿意翻译为『跑圈』.直观理解就像是不停 ...

  7. ios多线程原理及runloop介绍

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

  8. iOS多线程-RunLoop简介

    什么是RunLoop? 从字面上来看是运行循环的意思. 内部就是一个do{}while循环,在这个循环里内部不断的处理各种任务(比如:source/timer/Observer) RunLoop的存在 ...

  9. Runloop, 多线程

    Runloop是个死循环,为甚么? 1. 保证程序不退出 2.监听用户的事件, 触摸,时钟,网络事件 UITrackingMode,只能触摸事件,没有触摸事件了,直接就停止了 Runloop: sou ...

随机推荐

  1. Qt编程基础入门之二

    QMainWindow 菜单栏 菜单栏 最多有一个 //菜单栏创建,一个 QMenuBar *menu = new QMenuBar(this); // this->setMenuBar(men ...

  2. 【Linux】1 创建目录:mkdir

    mkdir命令用于创建目录,如同一路径下创建单个或多个目录.递归创建目录,但同路径下不能创建同名目录,且目录名区分大小写. [命令] mkdir [用途] 创建目录(单个目录/多个目录) [语法] m ...

  3. 使用Hystrix的插件机制,解决在使用线程隔离时,threadlocal的传递问题

    背景 在我们的项目中,比较广泛地使用了ThreadLocal,比如,在filter层,根据token,取到用户信息后,就会放到一个ThreadLocal变量中:在后续的业务处理中,就会直接从当前线程, ...

  4. 武装你的WEBAPI-OData入门

    本文属于OData系列 目录(可能会有后续修改) 武装你的WEBAPI-OData入门 武装你的WEBAPI-OData便捷查询 武装你的WEBAPI-OData分页查询 武装你的WEBAPI-ODa ...

  5. CF-612D The Union of k-Segments 差分

    D. The Union of k-Segments 题意 给出n个线段,以及一个数字k,让求出有哪些线段:线段上所有的点至少被覆盖了k次. 思路 假如忽略掉线段的左右端点范围,肯定是使用差分来维护每 ...

  6. [hdu5101]计数问题

    http://acm.hdu.edu.cn/showproblem.php?pid=5101 题目大意:给n个集合,求从两个不同集合里面各取一个数使得它们的和大于给定数的方案数. ans=从所有数里面 ...

  7. 想要年薪百万,阿里Sentinel支持RESTful接口都搞不定?

    最近正准备用阿里Sentinel,发现RESTful接口支持的不是很好.有些童鞋可能对Sentinel不是很了解,我们先简单介绍一下. Sentinel简介 Sentinel是一套阿里巴巴开源的流量防 ...

  8. 浅谈PostgreSQL用户权限

    问题 经常在PG群里看到有人在问“为什么我对表赋予了权限:但是还是不能访问表” 解析 若你看懂德哥这篇文章PostgreSQL逻辑结构和权限体系介绍:上面对你就不是困扰你的问题 解决这个问题很简单:在 ...

  9. dTree

    1.dtree.js源码 /*--------------------------------------------------| | dTree 2.05 | www.destroydrop.co ...

  10. Error creating bean with name 'org.springframework.aop.aspectj.AspectJPointc

    问题 出现报错: Error creating bean with name 'org.springframework.aop.aspectj.AspectJPointc 原因 缺失两个库文件: as ...