(1)單例形式
在順序運轉進程,一個類只要一個實例
(2)運用場所
在整個使用順序中,共享一份資源(這份資源只需求創立初始化1次)
1.2 ARC完成單例
(1)步驟
01 在類的外部提供一個static修飾的全局變量
02 提供一個類辦法,方便外界訪問
03 重寫+allocWithZone辦法,保證永遠都只為單例對象分配一次內存空間
04 嚴謹起見,重寫-copyWithZone辦法和-MutableCopyWithZone辦法
(2)相關代碼
//提供一個static修飾的全局變量,強援用著曾經實例化的單例對象實例
static XMGTools *_instance;
//類辦法,前往一個單例對象
+(instancetype)shareTools
{
//留意:這裡建議運用self,而不是直接運用類名Tools(思索承繼)
return [[self alloc]init];
}
//保證永遠只分配一次存儲空間
+(instancetype)allocWithZone:(struct _NSZone *)zone
{
//運用GCD中的一次性代碼
// static dispatch_once_t onceToken;
// dispatch_once(&onceToken, ^{
// _instance = [super allocWithZone:zone];
// });
//運用加鎖的方式,保證只分配一次存儲空間
@synchronized(self) {
if (_instance == nil) {
_instance = [super allocWithZone:zone];
}
}
return _instance;
}
/*
1. mutableCopy 創立一個新的可變對象,並初始化為原對象的值,新對象的援用計數為 1;
2. copy 前往一個不可變對象。分兩種狀況:(1)若原對象是不可變對象,那麼前往原對象,並將其援用計數加 1 ;(2)若原對象是可變對象,那麼創立一個新的不可變對象,並初始化為原對象的值,新對象的援用計數為 1。
*/
//讓代碼愈加的嚴謹
-(nonnull id)copyWithZone:(nullable NSZone *)zone
{
// return [[self class] allocWithZone:zone];
return _instance;
}
-(nonnull id)mutableCopyWithZone:(nullable NSZone *)zone
{
return _instance;
}
1.3 MRC完成單例
(1)完成步驟
01 在類的外部提供一個static修飾的全局變量
02 提供一個類辦法,方便外界訪問
03 重寫+allocWithZone辦法,保證永遠都只為單例對象分配一次內存空間
04 嚴謹起見,重寫-copyWithZone辦法和-MutableCopyWithZone辦法
05 重寫release辦法
06 重寫retain辦法
07 建議在retainCount辦法中前往一個最大值
(2)配置MRC環境知識
01 留意ARC不是渣滓回收機制,是編譯器特性
02 配置MRC環境:build setting ->搜索automatic ref->修正為NO
(3)相關代碼
//提供一個static修飾的全局變量,強援用著曾經實例化的單例對象實例
static XMGTools *_instance;
//類辦法,前往一個單例對象
+(instancetype)shareTools
{
//留意:這裡建議運用self,而不是直接運用類名Tools(思索承繼)
return [[self alloc]init];
}
//保證永遠只分配一次存儲空間
+(instancetype)allocWithZone:(struct _NSZone *)zone
{
//運用GCD中的一次性代碼
// static dispatch_once_t onceToken;
// dispatch_once(&onceToken, ^{
// _instance = [super allocWithZone:zone];
// });
//運用加鎖的方式,保證只分配一次存儲空間
@synchronized(self) {
if (_instance == nil) {
_instance = [super allocWithZone:zone];
}
}
return _instance;
}
//讓代碼愈加的嚴謹
-(nonnull id)copyWithZone:(nullable NSZone *)zone
{
// return [[self class] allocWithZone:zone];
return _instance;
}
-(nonnull id)mutableCopyWithZone:(nullable NSZone *)zone
{
return _instance;
}
//在MRC環境下,假如用戶retain了一次,那麼直接前往instance變量,不對援用計數器+1
//假如用戶release了一次,那麼什麼都不做,由於單例形式在整個順序運轉進程中都擁有且只要一份,順序加入之後被釋放,所以不需求對援用計數器操作
-(oneway void)release
{
}
-(instancetype)retain
{
return _instance;
}
//習用法,有經歷的順序員經過打印retainCount這個值可以猜到這是一個單例
-(NSUInteger)retainCount
{
return MAXFLOAT;
}
1.4 通用版本
(1)有意思的對話
01 問:寫一份單例代碼在ARC和MRC環境下都適用?
答:可以運用條件編譯來判別以後項目環境是ARC還是MRC
02 問:條件編譯的代碼呢,麼麼哒?
//答:條件編譯
#if __has_feature(objc_arc)
//假如是ARC,那麼就執行這裡的代碼1
#else
//假如不是ARC,那麼就執行代理的代碼2
#endif
03 問:在項目外面往往需求完成很多的單例,比方下載、網絡懇求、音樂播放等等,弱弱的問一句單例可以用承繼嗎?
答:單例是不可以用承繼的,假如想一次寫就,四處運用,那麼引薦親運用帶參數的宏定義啦!
04 問:宏定義怎樣弄?
答:這個嘛~~回頭看一眼我的代碼咯,親。
(2)運用帶參數的宏完成通用版單例形式代碼
01 留意條件編譯的代碼不能包括在宏定義外面
02 宏定義的代碼只需求寫一次就好,之後直接拖到項目中用就OK
2.NSOperation
2.1 NSOperation根本運用
(1)相關概念
01 NSOperation是對GCD的包裝
02 兩個中心概念【隊列+操作】
(2)根本運用
01 NSOperation自身是籠統類,只能只要它的子類
02 三個子類辨別是:NSBlockOperation、NSInvocationOperation以及自定義承繼自NSOperation的類
03 NSOperation和NSOperationQueue結合運用完成多線程並發
(3)相關代碼
// 01 NSInvocationOperation
//1.封裝操作
/*
第一個參數:目的對象
第二個參數:該操作要調用的辦法,最多承受一個參數
第三個參數:調用辦法傳遞的參數,假如辦法不承受參數,那麼該值傳nil
*/
NSInvocationOperation *operation = [[NSInvocationOperation alloc]
initWithtarget:self selector:@selector(run) object:nil];
//2.啟動操作
[operation start];
-------------------------------------------------
// 02 NSBlockOperation
//1.封裝操作
/*
NSBlockOperation提供了一個類辦法,在該類辦法中封裝操作
*/
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
//在主線程中執行
NSLog(@"---download1--%@",[NSThread currentThread]);
}];
//2.追加操作,追加的操作在子線程中執行
[operation addExecutionBlock:^{
NSLog(@"---download2--%@",[NSThread currentThread]);
}];
[operation addExecutionBlock:^{
NSLog(@"---download3--%@",[NSThread currentThread]);
}];
//3.啟動執行操作
[operation start];
----------------------------------------------
// 03 自定義NSOperation
//如何封裝操作?
//自定義的NSOperation,經過重寫外部的main辦法完成封裝操作
-(void)main
{
NSLog(@"--main--%@",[NSThread currentThread]);
}
//如何運用?
//1.實例化一個自定義操作對象
XMGOperation *op = [[XMGOperation alloc]init];
//2.執行操作
[op start];
2.2 NSOperationQueue根本運用
(1)NSOperation中的兩種隊列
01 客隊列 經過mainQueue取得,但凡放到客隊列中的義務都將在主線程執行
02 非客隊列 直接alloc init出來的隊列。非客隊列同時具有了並發和串行的功用,經過設置最大並發數屬性來控制義務是並發執行還是串行執行
(2)相關代碼
//自定義NSOperation
-(void)customOperation
{
//1.創立隊列
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
//2.封裝操作
//益處:1.信息蔭蔽
//2.代碼復用
XMGOperation *op1 = [[XMGOperation alloc]init];
XMGOperation *op2 = [[XMGOperation alloc]init];
//3.添加操作到隊列中
[queue addOperation:op1];
[queue addOperation:op2];
}
//NSBlockOperation
- (void)block
{
//1.創立隊列
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
//2.封裝操作
NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"1----%@",[NSThread currentThread]);
}];
NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"2----%@",[NSThread currentThread]);
}];
[op2 addExecutionBlock:^{
NSLog(@"3----%@",[NSThread currentThread]);
}];
[op2 addExecutionBlock:^{
NSLog(@"4----%@",[NSThread currentThread]);
}];
//3.添加操作到隊列中
[queue addOperation:op1];
[queue addOperation:op2];
//補充:簡便辦法
[queue addOperationWithBlock:^{
NSLog(@"5----%@",[NSThread currentThread]);
}];
}
//NSInvocationOperation
- (void)invocation
{
/*
GCD中的隊列:
串行隊列:自己創立的,客隊列
並發隊列:自己創立的,全局並發隊列
NSOperationQueue
客隊列:[NSOperationQueue mainqueue];凡事放在客隊列中的操作都在主線程中執行
非客隊列:[[NSOperationQueue alloc]init],並發和串行,默許是並發執行的
*/
//1.創立隊列
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
//2.封裝操作
NSInvocationOperation *op1 = [[NSInvocationOperation alloc]initWithtarget:self selector:@selector(download1) object:nil];
NSInvocationOperation *op2 = [[NSInvocationOperation alloc]initWithtarget:self selector:@selector(download2) object:nil];
NSInvocationOperation *op3 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(download3) object:nil];
//3.把封裝好的操作添加到隊列中
[queue addOperation:op1];//[op1 start]
[queue addOperation:op2];
[queue addOperation:op3];
}
2.3 NSOperation其它用法
(1)設置最大並發數【控制義務並發和串行】
//1.創立隊列
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
//2.設置最大並發數
//留意點:該屬性需求在義務添加到隊列中之行進行設置
//該屬性控制隊列是串行執行還是並發執行
//假如最大並發數等於1,那麼該隊列是串行的,假如大於1那麼是並行的
//零碎的最大並發數有個默許的值,為-1,假如該屬性設置為0,那麼不會執行任何義務
queue.maxConcurrentOperationCount = 2;
(2)暫停和恢復以及取消
//設置暫停和恢復
//suspended設置為YES表示暫停,suspended設置為NO表示恢復
//暫停表示不持續執行隊列中的下一個義務,暫停操作是可以恢復的
if (self.queue.isSuspended) {
self.queue.suspended = NO;
}else
{
self.queue.suspended = YES;
}
//取消隊列外面的一切操作
//取消之後,以後正在執行的操作的下一個操作將不再執行,而且永遠都不在執行,好像前面的一切義務都從隊列外面移除了一樣
//取消操作是不可以恢復的
[self.queue cancelAllOperations];
---------自定義NSOperation取消操作--------------------------
-(void)main
{
//耗時操作1
for (int i = 0; i<1000; i++) {
NSLog(@"義務1-%d--%@",i,[NSThread currentThread]);
}
NSLog(@"+++++++++++++++++++++++++++++++++");
//蘋果官方建議,每當執行完一次耗時操作之後,就檢查一下以後隊列能否為取消形態,假如是,那麼就直接加入
//益處是可以進步順序的功能
if (self.isCancelled) {
return;
}
//耗時操作2
for (int i = 0; i<1000; i++) {
NSLog(@"義務1-%d--%@",i,[NSThread currentThread]);
}
NSLog(@"+++++++++++++++++++++++++++++++++");
}
2.4 NSOperation完成線程間通訊
(1)開子線程下載圖片
//1.創立隊列
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
//2.運用簡便辦法封裝操作並添加到隊列中
[queue addOperationWithBlock:^{
//3.在該block中下載圖片
NSURL *url = [NSURL URLWithString:@"http://news.51sheyuan.com/uploads/allimg/111001/133442IB-2.jpg"];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];
NSLog(@"下載圖片操作--%@",[NSThread currentThread]);
//4.回到主線程刷新UI
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
self.imageView.image = image;
NSLog(@"刷新UI操作---%@",[NSThread currentThread]);
}];
}];
(2)下載多張圖片分解綜合案例(設置操作依賴)
//02 綜合案例
- (void)download2
{
NSLog(@"----");
//1.創立隊列
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
//2.封裝操作下載圖片1
NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
NSURL *url = [NSURL URLWithString:@"http://h.hiphotos.baidu.com/zhidao/pic/item/6a63f6246b600c3320b14bb3184c510fd8f9a185.jpg"];
NSData *data = [NSData dataWithContentsOfURL:url];
//拿到圖片數據
self.image1 = [UIImage imageWithData:data];
}];
//3.封裝操作下載圖片2
NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
NSURL *url = [NSURL URLWithString:@"http://pic.58pic.com/58pic/13/87/82/27Q58PICYje_1024.jpg"];
NSData *data = [NSData dataWithContentsOfURL:url];
//拿到圖片數據
self.image2 = [UIImage imageWithData:data];
}];
//4.分解圖片
NSBlockOperation *combine = [NSBlockOperation blockOperationWithBlock:^{
//4.1 開啟圖形上下文
UIGraphicsBeginImageContext(CGSizeMake(200, 200));
//4.2 畫image1
[self.image1 draWinRect:CGRectMake(0, 0, 200, 100)];
//4.3 畫image2
[self.image2 draWinRect:CGRectMake(0, 100, 200, 100)];
//4.4 依據圖形上下文拿到圖片數據
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
// NSLog(@"%@",image);
//4.5 封閉圖形上下文
UIGraphicsEndImageContext();
//7.回到主線程刷新UI
[[NSOperationQueue mainQueue]addOperationWithBlock:^{
self.imageView.image = image;
NSLog(@"刷新UI---%@",[NSThread currentThread]);
}];
}];
//5.設置操作依賴
[combine addDependency:op1];
[combine addDependency:op2];
//6.添加操作到隊列中執行
[queue addOperation:op1];
[queue addOperation:op2];
[queue addOperation:combine];
}
3.多圖下載綜合示例順序
(1)觸及知識點
01 字典轉模型
02 存儲數據到沙盒,從沙盒中加載數據
03 占位圖片的設置(cell的刷新問題)
04 如何停止內存緩存(運用NSDictionary)
05 在順序開發進程中的一些容錯處置
06 如何刷新tableView的指定行(處理數據紊亂問題)
07 NSOperation以及線程間通訊相關知識
4.第三方框架
(1)SDWebImage根本運用
01 設置imageView的圖片
[cell.imageView sd_setImageWithURL:[NSURL URLWithString:app.icon] placeholderImage:[UIImage imageNamed:@"placehoder"]];
02 設置圖片並計算下載進度
//下載並設置圖片
/*
第一個參數:要下載圖片的url地址
第二個參數:設置該imageView的占位圖片
第三個參數:傳一個枚舉值,通知順序你下載圖片的戰略是什麼
第一個block塊:獲取以後圖片數據的下載進度
receivedSize:曾經下載完成的數據大小
expectedSize:該文件的數據總大小
第二個block塊:當圖片下載完成之後執行該block中的代碼
image:下載失掉的圖片數據
error:下載呈現的錯誤信息
SDImageCacheType:圖片的緩存戰略(不緩存,內存緩存,沙盒緩存)
imageURL:下載的圖片的url地址
*/
[cell.imageView sd_setImageWithURL:[NSURL URLWithString:app.icon] placeholderImage:[UIImage imageNamed:@"placehoder"] options:SDWebImageRetryFailed progress:^(NSInteger receivedSize, NSInteger expectedSize) {
//計算以後圖片的下載進度
NSLog(@"%.2f",1.0 *receivedSize / expectedSize);
} completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
}];
03 零碎級內存正告如何處置(面試)
//取消以後正在停止的一切下載操作
[[SDWebImageManager sharedManager] cancelAll];
//肅清緩存數據(面試)
//cleanDisk:刪除過時的文件數據,計算以後未過時的曾經下載的文件數據的大小,假如發現該數據大小大於我們設置的最大緩存數據大小,那麼順序外部會依照按文件數據緩存的時間從遠到近刪除,知道小於最大緩存數據為止。
//clearMemory:直接刪除文件,重新創立新的文件夾
//[[SDWebImageManager sharedManager].imageCache cleanDisk];
[[SDWebImageManager sharedManager].imageCache clearMemory];
04 SDWebImage默許的緩存時間是1周
05 如何播放gif圖片
/*
5-1 把用戶傳入的gif圖片->NSData
5-2 依據該Data創立一個圖片數據源(NSData->CFImageSourceRef)
5-3 計算該數據源中一共有多少幀,把每一幀數據取出來放到圖片數組中
5-4 依據失掉的數組+計算的動畫時間-》可動畫的image
[UIImage animatedImageWithImages:images duration:duration];
*/
06 如何判別以後圖片類型
+ (NSString *)sd_contentTypeForImageData:(NSData *)data;
(2)SDWebImage外部構造
【iOS之多線程單例形式、NSOperation、多圖下載、SDWebImage】的相關資料介紹到這裡,希望對您有所幫助! 提示:不會對讀者因本文所帶來的任何損失負責。如果您支持就請把本站添加至收藏夾哦!