iOS-多线程笔记

零、线程的注意点(掌握)
1.不要同时开太多的线程(1~3条线程即可,不要超过5条)
2.线程概念
1> 主线程 : UI线程,显示、刷新UI界面,处理UI控件的事件
2> 子线程 : 后台线程,异步线程
3.不要把耗时的操作放在主线程,要放在子线程中执行

一、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个星期

3> SDWebImage底层是怎么实现的?
* 上课PPT的“cell下载图片思路 – 有沙盒缓存”

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个功能

时间: 2024-11-07 17:18:25

iOS-多线程笔记的相关文章

IOS学习笔记 -- 多线程

多线程1.多线程的原理 1>.同一时间,CPU只能处理1条线程,只有1条线程在工作(执行) 2>.多线程并发(同时)执行,其实是CPU快速地在多条线程之间调度(切换) 3>.如果CPU调度线程的时间足够快,就造成了多线程并发执行的假象如果线程非常非常多,会发生: 1>.CPU会在N多线程之间调度,CPU会累死,消耗大量的CPU资源 2>.每条线程被调度执行的频次会降低(线程的执行效率降低) 2.多线程的优缺点 1>.多线程的优点 能适当提高程序的执行效率 能适当提高资源

iOS 多线程学习笔记 —— GCD

本文复制.参考自文章:iOS多线程编程之Grand Central Dispatch(GCD)介绍和使用 ,主要为了加强个人对知识的理解和记忆,不做他用.原作者声明: 著作权声明:本文由http://blog.csdn.net/totogo2010/原创,欢迎转载分享.请尊重作者劳动,转载时保留该声明和作者博客链接,谢谢! 这里对原作者的辛勤工作表示感谢! 1. 简介 GCD (Grand Central Dispatch) 是建立任务并行执行的线程池模式的基础上的,以优化支持多核.多处理器系统

iOS 多线程学习笔记 —— NSOperation

本文复制.参考自文章:iOS多线程编程之NSOperation和NSOperationQueue的使用 ,主要为了加强个人对知识的理解和记忆,不做他用.原作者声明: 著作权声明:本文由http://blog.csdn.net/totogo2010/原创,欢迎转载分享.请尊重作者劳动,转载时保留该声明和作者博客链接,谢谢! 这里对原作者的辛勤工作表示感谢! 1. 使用抽象的 NSOperation 的方式有两种: (1)用库定义好的子类: NSInvocationOperation 和 NSBlo

iOS 多线程学习笔记

本文复制.参考自文章:iOS多线程编程之NSThread的使用  ,主要为了加强个人对知识的理解和记忆,不做他用.这里对原作者的辛勤工作表示感谢! 1. 简介 1.1 iOS的多线程编程技术分类 (1)NSThread (2) Cocoa NSOperation (3) GCD (Grand Central Dispatch) 这三种方式从上到下,抽象层次逐渐增高,使用也越来越简单. 1.2 三种方式的优缺点   优点 缺点 NSThread 轻量 需要自己管理线程的生命周期,线程同步.线程同步

iOS学习笔记-精华整理

iOS学习笔记总结整理 一.内存管理情况 1- autorelease,当用户的代码在持续运行时,自动释放池是不会被销毁的,这段时间内用户可以安全地使用自动释放的对象.当用户的代码运行告一段 落,开始等待用户的操作,自动释放池就会被释放掉(调用dealloc),池中的对象都会收到一个release,有可能会因此被销毁. 2-成员属性:     readonly:不指定readonly,默认合成getter和setter方法.外界毫不关心的成员,则不要设置任何属性,这样封装能增加代码的独立性和安全

iOS: 学习笔记, 值与引用类型(译自: https://developer.apple.com/swift/blog/ Aug 15, 2014 Value and Reference Type

值和引用类型 Value and Reference Types 在Swift中,有两种数据类型. 一是"值类型"(value type), 它是每一个实例都保存有各自的数据,通常定义为struct, enum或tuple. 二是"引用类型"(reference types),它是多实例共享一份数据,这种类型通常定义为class. 在本文中,我们将展示值类型和引用类型各自的优点以及如何在二者之间选择. 它们有什么区别? 最基本的区别是 "值类型"

iOS: 学习笔记, 值与引用类型(译自: https://developer.apple.com/swift/blog/ Aug 15, 2014 Value and Reference Types)

值和引用类型 Value and Reference Types 在Swift中,有两种数据类型. 一是"值类型"(value type), 它是每一个实例都保存有各自的数据,通常定义为struct, enum或tuple. 二是"引用类型"(reference types),它是多实例共享一份数据,这种类型通常定义为class. 在本文中,我们将展示值类型和引用类型各自的优点以及如何在二者之间选择. 它们有什么区别? 最基本的区别是 "值类型"

iOS学习笔记之ARC内存管理

iOS学习笔记之ARC内存管理 写在前面 ARC(Automatic Reference Counting),自动引用计数,是iOS中采用的一种内存管理方式. 指针变量与对象所有权 指针变量暗含了对其所指向对象的所有权 当某个方法(或函数)有一个指向某个对象的局部变量时,可以称该方法(或函数)拥有该变量所指向的对象,如: int main(int argc, const char * argv[]) { @autoreleasepool { // insert code here... NSSt

iOS学习笔记(十六)——数据库操作(使用FMDB)

iOS中原生的SQLite API在使用上相当不友好,在使用时,非常不便.于是,就出现了一系列将SQLite API进行封装的库,例如FMDB.PlausibleDatabase.sqlitepersistentobjects等,FMDB (https://github.com/ccgus/fmdb) 是一款简洁.易用的封装库,这一篇文章简单介绍下FMDB的使用. 在FMDB下载文件后,工程中必须导入如下文件,并使用 libsqlite3.dylib 依赖包. FMDB同时兼容ARC和非ARC工

iOS多线程 GCD

iOS多线程 GCD Grand Central Dispatch (GCD)是Apple开发的一个多核编程的解决方法. dispatch queue分成以下三种: 1)运行在主线程的Main queue,通过dispatch_get_main_queue获取. /*! * @function dispatch_get_main_queue * * @abstract * Returns the default queue that is bound to the main thread. *