多线程与RunLoop

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让这个线程常驻(不会执行完某次网络操作就杀掉)

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

时间: 2024-10-27 12:22:01

多线程与RunLoop的相关文章

iOS多线程 && Runloop

一.线程概述 有些程序是一条直线,起点到终点:有些程序是一个圆,不断循环,直到将它切断.直线的如简单的Hello World,运行打印完,它的生命周期便结束了,像昙花一现那样:圆如操作系统,一直运行直到你关机.  一个运行着的程序就是一个进程或者叫做一个任务,一个进程至少包含一个线程,线程就是程序的执行流.Mac和iOS中的程序启动,创建好一个进程的同时, 一个线程便开始运行,这个线程叫主线程.主线程在程序中的地位和其他线程不同,它是其他线程最终的父线程,且所有界面的显示操作即AppKit或 U

iOS中多线程原理与runloop介绍

http://mobile.51cto.com/iphone-403490.htm iOS中多线程原理与runloop介绍 iPhone中的线程应用并不是无节制的,官方给出的资料显示iPhone OS下的主线程的堆栈大小是1M,第二个线程开始都是512KB.并且该值不能通过编译器开关或线程API函数来更改.只有主线程有直接修改UI的能力.……>>详细 兄弟专题:iOS人机交互指南之UI设计基础 1 iOS多线程编程知多少 在iOS的世界里有两种实现多线程的方式: 多线程是一个比较轻量级的方法来

iOS开发多线程-RunLoop

一.什么是RunLoop 1.从字面意思看 1)运行循环 2)跑圈 2.基本作用 1)保持程序的持续运行 2)处理App中的各种事件(比如触摸事件.定时器事件.Selector事件) 3)节省CPU资源,提高程序性能:该做事时做事,该休息时休息 4)...... 3.如果没有RunLoop 说明:没有RunLoop的情况下,程序执行到第3行后程序就结束了 4.如果有了RunLoop 说明:有RunLoop的情况下,由于main函数里面启动了个RunLoop,所以程序并不会马上退出,保持持续运行状

多线程RunLoop

什么是RunLoop 从字面意思看运行循环跑圈 基本作用保持程序的持续运行处理App中的各种事件(比如触摸事件.定时器事件.Selector事件)节省CPU资源,提高程序性能:该做事时做事,该休息时休息...... 如果没有RunLoop 没有RunLoop的情况下第3行后程序就结束了 如果有了RunLoop 有RunLoop的情况下由于main函数里面启动了个RunLoop,所以程序并不会马上退出,保持持续运行状态  main函数中的RunLoop 第14行代码的UIApplicationMa

iOS多线程开发(二)---线程管理

线程管理 线程管理包括创建,配置,退出三部分.主要包括创建线程的成本,线程创建,线程属性配置,线程主体入口函数编写,线程中断等 一,线程创建成本 1,为辅助线程分配的堆栈空间大小,便于系统和进程管理,以及为函数参数和局部变量分配空间 A,内核数据结构(kernel data structures)---大约1KB,This memory is used to store the thread data structures and attributes, much of which is all

iOS多线程编程指南(二)线程管理

当应用程序生成一个新的线程的时候,该线程变成应用程序进程空间内的一个实体.每个线程都拥有它自己的执行堆栈,由内核调度独立的运行时间片.一个线程可以和其他线程或其他进程通信,执行I/O操作,甚至执行任何你想要它完成的任务.因为它们处于相同的进程空间,所以一个独立应用程序里面的所有线程共享相同的虚拟内存空间,并且具有和进程相同的访问权限. 一.线程成本 多线程会占用你应用程序(和系统的)的内存使用和性能方面的资源.每个线程都需要分配一定的内核内存和应用程序内存空间的内存.管理你的线程和协调其调度所需

Runloop(运行循环)是什么?

运行循环是什么?从介绍到演示 今天整理一下运行循环来帮朋友们了解一下什么是运行循环,也叫消息循环,建议大家称之为运行循环(Runloop). 关于多线程的运行循环(消息循环) 1. 什么是运行循环 (1)Runloop就是运行循环,每个线程内部都有一个运行循环. (2)只有主线程的运行循环默认是开启的,子线程的运行循环. 2. 运行循环的作用 (1)保证程序不退出,iOS的应用程序启动之后,之所以不会退出,就是因为有Runloop(运行循环).运行循环是一个死循环,只有满足一定条件才会结束循环.

iOS多线程——GCD篇

什么是GCD GCD是苹果对多线程编程做的一套新的抽象基于C语言层的API,结合Block简化了多线程的操作,使得我们对线程操作能够更加的安全高效. 在GCD出现之前Cocoa框架提供了NSObject类的 performSelectorInBackground:withObject performSelectorOnMainThread 方法来简化多线程编程技术. GCD可以解决以下多线程编程中经常出现的问题:1.数据竞争(比如同时更新一个内存地址) 2.死锁(互相等待) 3.太多线程导致消耗

【iOS开发每日小笔记(九)】在子线程中使用runloop,正确操作NSTimer计时的注意点 三种可选方法

这篇文章是我的[iOS开发每日小笔记]系列中的一片,记录的是今天在开发工作中遇到的,可以用很短的文章或很小的demo演示解释出来的小心得小技巧.它们可能会给用户体验.代码效率得到一些提升,或是之前自己没有接触过的技术,很开心的学到了,放在这里得瑟一下.其实,90%的作用是帮助自己回顾.记忆.复习. 一直想写一篇关于runloop学习有所得的文章,总是没有很好的例子.正巧自己的上线App Store的小游戏<跑酷好基友>(https://itunes.apple.com/us/app/pao-k