进程和线程

要使用多线程,首先需要理解进程和线程这2个概念。这里我简单的说一下。

所谓进程对应的是一个应用程序,负责开辟内存空间供应用程序使用,但是进程不能执行任务(指令)。一个进程至少包含一条线程,线程是程序的执行流。

•iOS程序启动时,在创建一个进程的同时, 会开始运行一个线程,该线程被称为主线程
•系统中的每一个进程都有自己独立的虚拟内存空间,而同一个进程中的多个线程则共用进程的内存空间
•每创建一个新的线程,都会消耗一定内存和CPU时间
•当多个线程对同一个资源出现争夺的时候需要注意线程安全问题
 
多线程的应用及使用注意事项
将耗时、轮询或者并发需求高等任务分配到其他线程执行,并由主线程负责统一更新界面会使得应用程序更加流畅,用户体验更好,例如网络请求,播放游戏的背景音乐等。
•线程使用不是无节制的
–iOS中的主线程的堆栈大小是1M
–从第二个线程开始都是512KB
–这些数值不能通过编译器开关或线程API函数更改
注:更新UI界面,处理界面和用户之间的交互事件一定要在主线程中处理。
 
iOS中的多线程技术
 
1.NSObject的多线程方法-对NSThread的封装(一个NSThread对象对应一条线程)
 
•开启后台线程执行任务的方法
-(void)performSelectorInBackground:(SEL)aSelector withObject:(id)arg
•在后台线程中通知主线程执行任务的方法
–(void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;
•获取线程信息
[NSThread currentThread];
•线程休眠      
[NSThread sleepForTimeInterval:1.0f];

提示:

–performSelectorInBackground方法本身是在主线程中执行的,而选择器指定的方法是在后台线程中进行的
–尽管使用performSelectorInBackground方法调用的任务可以更新UI界面,但是在实际开发中,涉及到UI界面的更新操作,还是要使用performSelectorOnMainThread方法,以避免不必要的麻烦
注:
•内存管理对于多线程非常重要
•Objective-C可以凭借@autoreleasepool使用内存资源,并需要时回收资源
•每个线程都需要有@autoreleasepool,否则可能会出现内存泄漏
 
2.NSThread
 
•创建线程方法:
1.+ (void)detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(id)argument;
2.- (id)initWithTarget:(id)target selector:(SEL)selector object:(id)argument;
•参数说明:
–selector:线程执行的方法,只能有一个参数,不能有返回值
–target:selector消息发送的对象
–argument:传输给target的唯一参数,也可以是nil
 
3.NSOperation/NSOperationQueue
 
•NSOperation的两个子类
1.NSInvocationOperation
2.NSBlockOperation
 
•工作原理:
1.用NSOperation封装要执行的操作
2.将创建好的NSOperation对象放NSOperationQueue中
3.启动OperationQueue开始新的线程执行队列中的操作
•注意事项:
1.使用多线程时通常需要控制线程的并发数,因为线程会消耗系统资源,同时运行的线程过多,系统会变慢
2.使用以下方法可以控制并发的线程数量:
-(void)setMaxConcurrentOperationCount:(NSInteger)cnt;
3.使用addDependency可以建立操作之间的依赖关系,设定操作的执行顺序
 
上面的程序设置依赖关系后,只有等操作a和b都执行完,才会执行c.
 
4.GCD
 
•GCD队列:
1.全局队列:所有添加到主队列中的任务都是并发执行的(可能会开启多条线程)
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
2.串行队列:所有添加到串行队列中的任务都是顺序执行的(只可能会开启一条线程)
dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_SERIAL);
3.主队列:所有添加到主队列中的任务都是在主线程中执行的
dispatch_get_main_queue();

•异步操作
–dispatch_async 在其他线程执行任务,会开启新的线程
–异步方法无法确定任务的执行顺序
•同步操作
–dispatch_sync 在当前在线程执行任务,不开启新的线程
–同步操作与队列无关
–同步方法会依次执行,能够决定任务的执行顺序
–更新界面UI时,最好使用同步方法
注:同步还是异步,取决于方法名(不影响主队列,影响全局队列、串行队列)。
 
试例1:

分析:虽然任务都是添加到全局队列中,但是都是同步操作,所以不会开启新的线程,是在当前线程中执行任务。

试例2:

分析:将3个任务添加到串行队列中,虽然是异步的操作,会开启新的线程,但最多最会开启一个。

试例3:

分析:不管是同步还是异步的任务添加到主队列中,都是在主线程中执行

多线程技术在iOS开发中的使用的更多相关文章

  1. 多线程在iOS开发中的应用

    多线程基本概念 01 进程 进程是指在系统中正在运行的一个应用程序.每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内. 02 线程 2-1 基本概念 1个进程要想执行任务,必须得有线程 ...

  2. iOS开发中各种关键字的区别

    1.一些概念 1.浅Copy:指针的复制,只是多了一个指向这块内存的指针,共用一块内存. 深Copy:内存的复制,两块内存是完全不同的, 也就是两个对象指针分别指向不同的内存,互不干涉. 2.atom ...

  3. iOS开发中静态库制作 之.a静态库制作及使用篇

    iOS开发中静态库之".a静态库"的制作及使用篇 一.库的简介 1.什么是库? 库是程序代码的集合,是共享程序代码的一种方式 2.库的类型? 根据源代码的公开情况,库可以分为2种类 ...

  4. fir.im Weekly - iOS开发中的Git流程

    本期 fir.im Weekly 收集了微博上的热转资源,包含 Android.iOS 开发工具.源码等好用的轮子,还有一些 APP 设计的 Tips,希望对你有用. 精仿知乎日报 iOS 端 @我偏 ...

  5. IOS开发中UI编写方式——code vs. xib vs.StoryBoard

    最近接触了几个刚入门的iOS学习者,他们之中存在一个普遍和困惑和疑问,就是应该如何制作UI界面.iOS应用是非常重视用户体验的,可以说绝大多数的应用成功与否与交互设计以及UI是否漂亮易用有着非常大的关 ...

  6. iOS开发中的4种数据持久化方式【一、属性列表与归档解档】

    iOS中的永久存储,也就是在关机重新启动设备,或者关闭应用时,不会丢失数据.在实际开发应用时,往往需要持久存储数据的,这样用户才能在对应用进行操作后,再次启动能看到自己更改的结果与痕迹.ios开发中, ...

  7. 在iOS开发中使用FMDB

    在iOS开发中使用FMDB 前言 SQLite (http://www.sqlite.org/docs.html) 是一个轻量级的关系数据库.iOS SDK 很早就支持了 SQLite,在使用时,只需 ...

  8. iOS开发中你是否遇到这些经验问题

    前言 小伙伴们在开发中难免会遇到问题, 你是如何解决问题的?不妨也分享给大家!如果此文章其中的任何一条问题对大家有帮助,那么它的存在是有意义的! 反正不管怎样遇到问题就要去解决问题, 在解决问题的同时 ...

  9. 简述 Ruby 与 DSL 在 iOS 开发中的运用

    阅读本文不需要预先掌握 Ruby 与 DSL 相关的知识 何为 DSL DSL(Domain Specific Language) 翻译成中文就是:"领域特定语言".首先,从定义就 ...

随机推荐

  1. android 项目学习随笔四(优化ViewPager)

    1.不能滑动的ViewPager import android.content.Context; import android.support.v4.view.ViewPager; import an ...

  2. JVM复习笔记

    1. JVM是什么? JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来 ...

  3. 使用Mysql ID自增长时 在Mapper的<insert>里添加对应的代码

    <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Long&quo ...

  4. iOS 学习笔记 一 (2015.02.05)

    一:Xcode6输入框设置为 keyboard type设置为Number Pad弹不出键盘的解决办法   问题:Can't find keyplane that supports type 4 fo ...

  5. cocospod 安装和使用

    一 ruby 安装 要安装coocspod 首先需要安装ruby,可以先安装xcode,在安装macport 下载地址,最后执行命令 port install ruby 二.安装CocoaPods 1 ...

  6. symfony中twig的模板载入

    模板 载入模板 {% include ‘sidebar.html’ %} 当前模板的变量也会传递到 被include的模板里,在那里面可以直接访问你这个模板的变量. {% for comment in ...

  7. 为ecshop红包增加”转赠”功能

    ecshop促销中使用红包激励用户购物,要想炒热活动,红包就需要有物以稀为贵的感觉.有人求有人送,这样红包之间的转赠有助于拉动第二梯队的顾客.但是如果已经把红包添加到自己的账户了怎么办?如果ecsho ...

  8. 理解css中的position-static\relative\fixed\absolute

    position属性有四个值: static(静态定位):是默认值,不会被特殊的定位,遵循正常的文档流对象,对象占用文档空间,该方式下,top.right.bottom.left.z-index等属性 ...

  9. jQuery 禁用退格键

    在只读区域按退格键会造成页面后退,禁用退格键可以这样做: $(document).bind("keydown", function(e){ if(e.keyCode == 8){/ ...

  10. Javascript事件委托

      事件委托利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件未使用事件委托之前: <!DOCTYPE html> <html> <head> &l ...