一 多线程基础面试
1.进程:进程就是系统中正在运行的应用程序.每一个进程是相互独立的且都运行在各自受保护的运行空间内. 编程
好比同时打开迅雷、Xcode,系统就会分别启动2个进程.缓存
2.线程:进程在执行任务是必须开辟线程,进程中的全部任务都在线程中进行.一个进程能够开辟一条线程,也能够开辟多条线程.安全
好比酷狗音乐这个进程在执行播放音乐这个线程的同时,还在执行下载音乐这条线线程.多线程
二 线程的串行并发
在同一时间一个线程只能执行一个任务,若是一个线程有多条任务要执行就得按前后顺序执行,一个线程不能同时进行多个任务.app
三 多线程框架
一个进程能够开辟多条线程,每条线程能够执行不一样的任务,看上去是每条相称在同时进行,实际上是CPU在不一样线程间快速的切换.异步
CPU在同一时间只能执行一条线程.async
多线程技术能够提升执行程序的效率,提升资源利用率.
可是在建立线程耗内存耗时间,且若是线程开辟太多也会下降程序的性能,并且多线程的程序设计难度也更大.
四 多线程在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_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
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:^{ }]; }];
十一 从其余线程回到主线程的方式
//perform... [self performSelectorOnMainThread:<#(SEL)#> withObject:<#(id)#> waitUntilDone:<#(BOOL)#>]; //GCD dispatch_async(dispatch_get_main_queue(), ^{ }); //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个功能