一 多線程基礎面試
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個功能