内容简介:iOS多线程编程各种方式总结iOS中多线程的实现方式有如下四种:
前言
iOS多线程编程各种方式总结
正文
一. 概述
iOS中多线程的实现方式有如下四种:
本文主要总结常用的两种方式
二. GCD
2.1 GCD概述
GCD即Grand Central Dispatch,是苹果公司为多核的并行运算提出的解决方案,能自动合理地利用多核CPU(比如双核、四核),同时还能自动管理线程的生命周期(创建线程、调度任务、销毁线程),不需要手动管理;由 C语言 实现
2.2 GCD使用
2.2.1 主要方法
dispatch_sync(dispatch_queue_t queue, dispatch_block_t block) dispatch_async(dispatch_queue_t queue, dispatch_block_t block) dispatch_barrier_async(dispatch_queue_t queue, dispatch_block_t block)
dispatch_async(queue, ^{ // reading }); dispatch_async(queue, ^{ // reading }); dispatch_barrier_sync(queue, ^{ // writing }); dispatch_async(queue, ^{ // reading }); dispatch_async(queue, ^{ // reading });
2.2.2 队列
GCD中有两个重要的概念:任务和队列
- 任务有两种执行方式:同步执行和异步执行,他们之间的区别是否会创建新的线程
- 队列:用于存放任务。有两种队列, 串行队列和并行队列;区别如下:
可以通过如下方式获取或者创建队列:
dispatch_queue_create dispatch_get_global_queue dispatch_get_main_queue
// 自己创建队列:第一个参数是标识符,用于 DEBUG 的时候标识唯一的队列; // 第二个参数用来表示创建的队列是串行的还是并行的,传入 DISPATCH_QUEUE_SERIAL 或 NULL 表示创建串行队列。传入 DISPATCH_QUEUE_CONCURRENT 表示创建并行队列 //串行队列 dispatch_queue_t queue = dispatch_queue_create("tk.bourne.testQueue", NULL); dispatch_queue_t queue = dispatch_queue_create("tk.bourne.testQueue", DISPATCH_QUEUE_SERIAL); //并行队列 dispatch_queue_t queue = dispatch_queue_create("tk.bourne.testQueue", DISPATCH_QUEUE_CONCURRENT);
// 全局并行队列: dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
2.2.3 队列组(Dispatch Group)
可用于实现当并行执行block时,监听所有block执行结束
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_group_t group = dispatch_group_create(); dispatch_group_async(group, queue, ^{ NSLog(@"Block 1"); }); dispatch_group_async(group, queue, ^{ NSLog(@"Block 2"); }); dispatch_group_async(group, queue, ^{ NSLog(@"Block 3"); }); dispatch_group_notify(group, dispatch_get_main_queue(), ^{ NSLog(@"Done"); });
应用举例:分别执行两个耗时的操作,等两个异步操作都执行完之后,回到主线程执行操作;如果想要高效实现上述需求,可用队列组;如下
dispatch_group_t group = dispatch_group_create(); dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // 执行1个耗时的异步操作 }); dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // 执行1个耗时的异步操作 }); dispatch_group_notify(group, dispatch_get_main_queue(), ^{ // 等前面的异步操作都执行完毕后,回到主线程... });
2.2.4 其他
- 延迟执行:通过
dispatch_walltime
生成绝对时间
dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, 3ull * NSEC_PER_SEC); // ull表示:unsigned long long dispatch_after(time, dispatch_get_main_queue(), ^{ });
- dipatch_apply:相当于dipatch_sync和dispatch group的关联API,该函数将指定的block追加到指定的queue中,并等待全部处理执行结束;其也会阻塞直到执行完毕,可用其替代for循环
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_apply(10, queue, ^(size_t index) { // index表示当前索引,自动增加 NSLog(@"%zu", index); }); NSLog(@"Done"); // 最后执行
-
dispatch_suspend / dispatch_resume:用于挂起和恢复queue
-
Dispatch Semaphore:计数为0时等待,计数为1或大于1时,减1而不是等待
-
dispatch_once:保证在应用程序中只执行一次指定处理的API
- Dispatch IO:当读取大文件时,将文件分成合适的大小并使用Global Queue读取的话,会快很多,如果想尝试提高文件读取速度,可以使用Dispatch IO
2.2.5 备注
在iOS6.0之前,在GCD中每当使用带creat单词的函数创建对象之后,都应该对其进行一次release操作。在iOS6.0之后,GCD被纳入到了ARC的内存管理机制中,在使用GCD的时候我们就像对待普通OC对象一样对待GCD,因此不再需要我们调用release方法
三. NSOperation
- 本身是个抽象类,需要使用其子类:NSInvocationOperation,NSBlockOperation,或自定义子类
- 默认情况下,调用 NSInvocationOperation 的 start 方法并不会开一条新线程去执行,而是在当前线程执行;需要把 NSOperation 放到一个 NSOperationQueue 中才会执行异步操作
- NSBlockOperation:只要 NSBlockOperation 封装的操作数 > 1,就会异步执行操作
- 支持取消,暂停和恢复,还可以设置依赖来保证执行顺序,如
[operationB addDependency:operationA]; // 操作B依赖于操作A
;还可以在不同 queue 的 NSOperation 之间创建依赖关系 - 支持监听一个操作的执行完毕:通过
completionBlock
和setCompletionBlock
实现
四. 网络请求
网络请求常用类:
- NSURL:请求地址
- NSURLRequest:一个NSURLRequest对象就代表一个请求,它包含的信息有:一个 NSURL 对象,请求方法,请求头,请求体,请求超时等
- NSMutableURLRequest:NSURLRequest的子类
- NSURLConnection:负责发送请求;支持发送同步请求(sendSynchronousRequest)和异步请求(sendAsynchronousRequest);还可以设置代理监听网络请求过程(开始响应,接收数据,结束响应,请求出错)
第三方框架:
- ASIHttpRequest
- AFNetworking
- MKNetworkKit
iOS中发送 HTTP 请求的方案:
- 苹果原生
- NSURLConnection:用法简单,坑较多
- NSURLSession:功能比 NSURLConnection 强大,苹果推荐使用(但是NSURLSessionTask是一个抽象类,本身不能使用,只能使用它的子类:NSURLSessionDataTask\NSURLSessionUploadTask\NSURLSessionDownloadTask)
- CFNetwork:NSURL*的底层实现,纯C语言
两种为NSURLConnection设置代理方式的区别:
//第一种设置方式: //通过该方法设置代理,会自动的发送请求 // [[NSURLConnection alloc]initWithRequest:request delegate:self]; //第二种设置方式: //设置代理,startImmediately为NO的时候,该方法不会自动发送请求 NSURLConnection *connect = [[NSURLConnection alloc]initWithRequest:request delegate:self startImmediately:NO]; //手动通过代码的方式来发送请求 //注意该方法内部会自动的把connect添加到当前线程的RunLoop中在默认模式下执行 [connect start];
五. 数据解析
Json解析(转OC数据类型):
- 第三方框架:JSONKit、SBJson、TouchJSON(性能从左到右,越差)
- 苹果原生:NSJSONSerialization(性能最好)
XML解析:
- 解析方式有两种:
- DOM:一次性将整个XML文档加载进内存,比较适合解析小文件
- SAX:从根元素开始,按顺序一个元素一个元素往下解析,比较适合解析大文件
- 解析API:
- 官方原生:NSXMLParser,SAX方式解析
- libxml2:纯C语言,默认包含在iOS SDK中,同时支持DOM和SAX方式解析
- GDataXML:DOM方式解析,由Google开发,基于libxml2
六. RunLoop
RunLoop是iOS中比较重要的一点,较短篇幅无法讲完,后面有机会再另起新篇总结
七. 参考博客
- https://www.jianshu.com/p/0b0d9b1f1f19
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- python网络编程(进程与多线程)
- 你可曾听过网络编程中应用线程本地存储?
- 一步步动手实现高并发的Reactor模型 —— Kafka底层如何充分利用多线程优势去处理网络I/O与业务分发...
- java中线程安全,线程死锁,线程通信快速入门
- ObjC 多线程简析(一)-多线程简述和线程锁的基本应用
- Java多线程之线程中止
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Spring
Bruce Tate、Justin Gehtland / O'Reilly Media, Inc. / 2005-04-12 / USD 29.95
Since development first began on Spring in 2003, there's been a constant buzz about it in Java development publications and corporate IT departments. The reason is clear: Spring is a lightweight Java......一起来看看 《Spring》 这本书的介绍吧!