iOS 多线程
一 多线程基础
1.进程:进程就是系统中正在运行的应用程序.每个进程是相互独立的且都运行在各自受保护的运行空间内.
比如同时打开迅雷、Xcode,系统就会分别启动2个进程.
2.线程:进程在执行任务是必须开辟线程,进程中的所有任务都在线程中进行.一个进程可以开辟一条线程,也可以开辟多条线程.
比如酷狗音乐这个进程在执行播放音乐这个线程的同时,还在执行下载音乐这条线线程.
二 线程的串行
在同一时间一个线程只能执行一个任务,如果一个线程有多条任务要执行就得按先后顺序执行,一个线程不能同时进行多个任务.
三 多线程
一个进程可以开辟多条线程,每条线程可以执行不同的任务,看上去是每条相称在同时进行,其实是CPU在不同线程间快速的切换.
CPU在同一时间只能执行一条线程.
多线程技术可以提高执行程序的效率,提高资源利用率.
但是在创建线程耗内存耗时间,且如果线程开辟太多也会降低程序的性能,而且多线程的程序设计难度也更大.
四 多线程在IOS开发中的应用
一个iOS程序运行后,会自动开辟主线程(又叫UI线程).
主线程主要用来显示和刷新UI界面以及处理UI事件.
主线程使用过程中的注意事项:主线程处理耗时操作时会有卡死的感觉,影响UI的流畅度,因此不可将耗时较多的操作放在主线程中.
主线程只用来显示和刷新UI界面以及处理UI事件.
五 多线程的实现方案
1.pthread 几乎不用
2.NSThread 几乎不用
3.GCD 常使用
GCD基于C语言,自动管理现成的生命周期,可从分利用多喝处理器来处理线程.
4.NSOperation 常使用
NSOperation基于GCD自动管理线程的生命周期.
六 NSThread(掌握)
1.创建和启动线程的3种方式
1> 先创建,后启动
// 创建
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(download:) object:nil];
// 启动
[thread start];
2> 创建完自动启动
[NSThread detachNewThreadSelector:@selector(download:) toTarget:self withObject:nil];
3> 隐式创建(自动启动)
[self performSelectorInBackground:@selector(download:) withObject:nil];
2.常见方法
1> 获得当前线程
+ (NSThread *)currentThread;
2> 获得主线程
+ (NSThread *)mainThread;
3> 睡眠(暂停)线程
+ (void)sleepUntilDate:(NSDate *)date;
+ (void)sleepForTimeInterval:(NSTimeInterval)ti;
4> 设置线程的名字
- (void)setName:(NSString *)n;
- (NSString *)name;
七 线程同步(掌握)
1.实质:为了防止多个线程抢夺同一个资源造成的数据安全问题
2.实现:给代码加一个互斥锁(同步锁)
@synchronized(self) {
// 被锁住的代码
}
八 GCD
1.队列和任务
1> 任务 :需要执行什么操作
* 用block来封装任务
2> 队列 :存放任务
* 全局的并发队列 : 可以让任务并发执行
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
* 自己创建的串行队列 : 让任务一个接着一个执行
dispatch_queue_t queue = dispatch_queue_create("cn.heima.queue", NULL);
* 主队列 : 让任务在主线程执行
dispatch_queue_t queue = dispatch_get_main_queue();
2.执行任务的函数
1> 同步执行 : 不具备开启新线程的能力
dispatch_sync...
2> 异步执行 : 具备开启新线程的能力
dispatch_async...
3.常见的组合(掌握)
1> dispatch_async + 全局并发队列
2> dispatch_async + 自己创建的串行队列
4.线程间的通信(掌握)
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 执行耗时的异步操作...
dispatch_async(dispatch_get_main_queue(), ^{
// 回到主线程,执行UI刷新操作
});
});
5.GCD的所有API都在libdispatch.dylib,Xcode会自动导入这个库
* 主头文件 : #import <dispatch/dispatch.h>
6.延迟执行(掌握)
1> perform....
// 3秒后自动回到当前线程调用self的download:方法,并且传递参数:@"http://555.jpg"
[self performSelector:@selector(download:) withObject:@"http://555.jpg" afterDelay:3];
2> dispatch_after...
// 任务放到哪个队列中执行
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
double delay = 3; // 延迟多少秒
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_SEC)), queue, ^{
// 3秒后需要执行的任务
});
7.一次性代码(掌握)
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// 这里面的代码,在程序运行过程中,永远只会执行1次
});
九 单例模式(懒汉式)
1.ARC
@interface HMDataTool : NSObject
+ (instancetype)sharedDataTool;
@end
@implementation HMDataTool
// 用来保存唯一的单例对象
static id _instace;
+ (id)allocWithZone:(struct _NSZone *)zone
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instace = [super allocWithZone:zone];
});
return _instace;
}
+ (instancetype)sharedDataTool
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instace = [[self alloc] init];
});
return _instace;
}
- (id)copyWithZone:(NSZone *)zone
{
return _instace;
}
@end
2.非ARC
@interface HMDataTool : NSObject
+ (instancetype)sharedDataTool;
@end
@implementation HMDataTool
// 用来保存唯一的单例对象
static id _instace;
+ (id)allocWithZone:(struct _NSZone *)zone
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instace = [super allocWithZone:zone];
});
return _instace;
}
+ (instancetype)sharedDataTool
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instace = [[self alloc] init];
});
return _instace;
}
- (id)copyWithZone:(NSZone *)zone
{
return _instace;
}
- (oneway void)release {
}
- (id)retain {
return self;
}
- (NSUInteger)retainCount {
return 1;
}
- (id)autorelease {
return self;
}
@end
十 NSOperation和NSOperationQueue
1.队列的类型
1> 主队列
* [NSOperationQueue mainQueue]
* 添加到"主队列"中的操作,都会放到主线程中执行
2> 非主队列
* [[NSOperationQueue alloc] init]
* 添加到"非主队列"中的操作,都会放到子线程中执行
2.队列添加任务
* - (void)addOperation:(NSOperation *)op;
* - (void)addOperationWithBlock:(void (^)(void))block;
3.常见用法
1> 设置最大并发数
- (NSInteger)maxConcurrentOperationCount;
- (void)setMaxConcurrentOperationCount:(NSInteger)cnt;
2> 队列的其他操作
* 取消所有的操作
- (void)cancelAllOperations;
* 暂停所有的操作
[queue setSuspended:YES];
* 恢复所有的操作
[queue setSuspended:NO];
4.操作之间的依赖(面试题)
* NSOperation之间可以设置依赖来保证执行顺序
* [operationB addDependency:operationA];
// 操作B依赖于操作A,等操作A执行完毕后,才会执行操作B
* 注意:不能相互依赖,比如A依赖B,B依赖A
* 可以在不同queue的NSOperation之间创建依赖关系
5.线程之间的通信
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperationWithBlock:^{
// 1.执行一些比较耗时的操作
// 2.回到主线程
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
}];
}];
十一 从其他线程回到主线程的方式
1.perform...
[self performSelectorOnMainThread:<#(SEL)#> withObject:<#(id)#> waitUntilDone:<#(BOOL)#>];
2.GCD
dispatch_async(dispatch_get_main_queue(), ^{
});
3.NSOperationQueue
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
}];
十二 判断编译器的环境:ARC还是MRC?
#if __has_feature(objc_arc)
// 当前的编译器环境是ARC
#else
// 当前的编译器环境是MRC
#endif
十三 类的初始化方法
1.+(void)load
* 当某个类第一次装载到OC运行时系统(内存)时,就会调用
* 程序一启动就会调用
* 程序运行过程中,只会调用1次
2.+(void)initialize
* 当某个类第一次被使用时(比如调用了类的某个方法),就会调用
* 并非程序一启动就会调用
3.在程序运行过程中:1个类中的某个操作,只想执行1次,那么这个操作放到+(void)load方法中最合适
十四 第三方框架的使用建议
1.用第三方框架的目的
1> 开发效率:快速开发,人家封装好的一行代码顶自己写的N行
2> 为了使用这个功能最牛逼的实现
2.第三方框架过多,很多坏处(忽略不计)
1> 管理、升级、更新
2> 第三方框架有BUG,等待作者解决
3> 第三方框架的作者不幸去世、停止更新(潜在的BUG无人解决)
4> 感觉:自己好水
3.比如
流媒体:播放在线视频、音频(边下载边播放)
非常了解音频、视频文件的格式
每一种视频都有自己的解码方式(C\C++)
4.总结
1> 站在巨人的肩膀上编程
2> 没有关系,使劲用那么比较稳定的第三方框架
十五 cell的图片下载
1.面试题
1> 如何防止一个url对应的图片重复下载
* “cell下载图片思路 – 有沙盒缓存”
2> SDWebImage的默认缓存时长是多少?
* 1个星期
2.SDWebImage
1> 常用方法
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder;
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options;
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock;
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress: (SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock;
2> 内存处理:当app接收到内存警告时
/**
* 当app接收到内存警告
*/
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application
{
SDWebImageManager *mgr = [SDWebImageManager sharedManager];
// 1.取消正在下载的操作
[mgr cancelAll];
// 2.清除内存缓存
[mgr.imageCache clearMemory];
}
3> SDWebImageOptions
* SDWebImageRetryFailed : 下载失败后,会自动重新下载
* SDWebImageLowPriority : 当正在进行UI交互时,自动暂停内部的一些下载操作
* SDWebImageRetryFailed | SDWebImageLowPriority : 拥有上面2个功能
iOS 多线程的更多相关文章
- iOS多线程主题
下面是:2个并发进程.和2个并发线程的示意图: 下面介绍三种多线程技术(Thread.Cocoa Operation.Grand Central Dispatch): 1.最轻量级Thread(需要自 ...
- iOS多线程技术方案
iOS多线程技术方案 目录 一.多线程简介 1.多线程的由来 2.耗时操作的模拟试验 3.进程和线程 4.多线程的概念及原理 5.多线程的优缺点和一个Tip 6.主线程 7.技术方案 二.Pthrea ...
- iOS 多线程GCD的基本使用
<iOS多线程简介>中提到:GCD中有2个核心概念:1.任务(执行什么操作)2.队列(用来存放任务) 那么多线程GCD的基本使用有哪些呢? 可以分以下多种情况: 1.异步函数 + 并发队列 ...
- iOS多线程到底不安全在哪里?
iOS多线程安全的概念在很多地方都会遇到,为什么不安全,不安全又该怎么去定义,其实是个值得深究的话题. 共享状态,多线程共同访问某个对象的property,在iOS编程里是很普遍的使用场景,我们就从P ...
- iOS多线程的详情使用示例--简进祥
大家都知道,在开发过程中应该尽可能减少用户等待时间,让程序尽可能快的完成运算.可是无论是哪种语言开发的程序最终往往转换成汇编语言进而解释成机器码来执行.但是机器码是按顺序执行的,一个复杂的多步操作只能 ...
- iOS多线程
关于iOS多线程 概述 这篇文章中,我不会说多线程是什么.线程和进程的区别.多线程有什么用,当然我也不会说什么是串行.什么是并行等问题,这些我们应该都知道的. 在 iOS 中其实目前有 4 套多线程方 ...
- iOS多线程学习及总结
能有份网上的存储资料,备以后提升及参考 iOS 多线程编程 简介 一. iOS有三种多线程编程的技术,分别是: 1. NSThread 2. Cocoa NSOp ...
- iOS多线程杂论
iOS多线程的分布 (1) NSThread (2) NSOperation (3) GCD 现在对下面三个进行一个个的分析,希望那里说得不对的地方希望简友们帮我指点一二. 1,NSThread 优点 ...
- iOS多线程开发
概览 大家都知道,在开发过程中应该尽可能减少用户等待时间,让程序尽可能快的完成运算.可是无论是哪种语言开发的程序最终往往转换成汇编语言进而解释成机器码来执行.但是机器码是按顺序执行的,一个复杂的多步操 ...
- iOS多线程编程之NSThread的使用
目录(?)[-] 简介 iOS有三种多线程编程的技术分别是 三种方式的有缺点介绍 NSThread的使用 NSThread 有两种直接创建方式 参数的意义 PS不显式创建线程的方法 下载图片的例子 ...
随机推荐
- 【原】KMeans与深度学习模型结合提高聚类效果
这几天在做用户画像,特征是用户的消费商品的消费金额,原始数据(部分)是这样的: id goods_name goods_amount 男士手袋 1882.0 淑女装 2491.0 女士手袋 345.0 ...
- Windows phone应用开发[21]-图片性能优化
在windows phone 中常在列表中会常包含比较丰富文字和图片混排数据信息. 针对列表数据中除了谈到listbox等控件自身数据虚拟化问题外.虽然wp硬件设备随着SDK 8.0 发布得到应用可使 ...
- Ubuntu16.04/LinuxMint18安装openjdk-7-jdk
LinuxMint18的安装源已经默认没有openjdk7了,所以要自己手动添加仓库,如下: sudo add-apt-repository ppa:openjdk-r/ppa sudo apt-ge ...
- Java语法
java语法: 一个java程序可以说是一系列对象的集合,而这些对象都要通过调用彼此的方法来协同工作. 对象: 对象是一个实例,例如:一只猫,它是一个对象,有状态和行为.它的状态状态有:颜色,名字,品 ...
- UnixC学习小结
1.malloc工作原理: malloc使用一个数据结构(链表)维护分配空间 链表的构成:分配的空间/上一个空间数据/下一个空间/空间大小等信息. 对malloc分配的空间不要 ...
- python面向对象进阶(八)
上一篇<Python 面向对象初级(七)>文章介绍了面向对象基本知识: 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个“函数”供使 ...
- html页面输入框input的美化
input输入框是网页必不可少的组件,可是每个浏览器对于输入框的显示样式各有不同 例如: 上图分别就是谷歌浏览器和IE浏览器自带显示的输入框,样式也不足人意,所以大多都会自己写样式 以下是一个简 ...
- <<< commons-fileupload 和 ajaxfileupload 实现局部上传
最近弄了一个上传,要求实现页面的局部刷新,Java的上传组件大多还是用的 commons-fileupload,网上搜索了好多的教程,太麻烦了,看到了ajaxfileupload这个插件,不错,实现简 ...
- Windows7微软官方原版镜像系统文件
Windows7微软官方原版镜像系统 Windows 7 是由微软公司(Microsoft)开发的操作系统,核心版本号为Windows NT 6.1.Windows 7可供家庭及 商业工作环境.笔记本 ...
- nginx虚拟主机配置小结
nginx的安装在lnmp环境搭建中已经介绍过了,配置文件在安装目录下的conf子目录下,主要主要分成四部分:main(全局设置).server(主机设置).upstream(负载均衡服务器设置).l ...