多線程02

多線程2

  • GCD隊列組:
  • 基本使用:
//0.創(chuàng)建隊列組
  dispatch_group_t group = dispatch_group_create();

  //1.創(chuàng)建隊列
  dispatch_queue_t queue  =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);

  //2.添加任務(wù)
  //dispatch_async:1)封裝任務(wù)&2)提交任務(wù)到隊列
  //dispatch_group_async:1)封裝任務(wù)&2)提交任務(wù)到隊列&3)把當(dāng)前的任務(wù)的執(zhí)行情況納入到隊列組的監(jiān)聽范圍中
  dispatch_group_async(group,queue, ^{
      NSLog(@"download1---%@",[NSThread currentThread]);
  });
  • 常用函數(shù)
 // 兩者配合使用,后面的異步任務(wù)被監(jiān)聽
  dispatch_group_enter(group);
  dispatch_group_leave(group);
 // 當(dāng)隊列中的任務(wù)執(zhí)行完后執(zhí)行block
 dispatch_group_notify(<#dispatch_group_t group#>, <#dispatch_queue_t queue#>, <#^(void)block#>)
 // 一直到前面的代碼塊都執(zhí)行完,下面的代碼塊才執(zhí)行
 dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
  • 隊列和組隊列的區(qū)別
  • 隊列:封裝任務(wù),添加任務(wù)到隊列
  • 組隊列:封裝任務(wù),添加任務(wù)到隊列,添加隊列到組
  • 單例模式設(shè)計:
  • 設(shè)計分析:
  //1.靜態(tài)變量
 static XMGTool *_instance;

 //2.重寫分配空間的方法(alloc會重寫allocWithZone方法)
 //alloc --->allocWithZone
 +(instancetype)allocWithZone:(struct _NSZone *)zone
 {

 //解決安全問題
 /*
 @synchronized(self) {
     if (_instance == nil) {
         _instance = [super allocWithZone:zone];
     }
 }
  */
 static dispatch_once_t onceToken;
 dispatch_once(&onceToken, ^{
     _instance = [super allocWithZone:zone];
 });
 return _instance;
 }

 //3.提供類方法
 +(instancetype)shareXMGTool
 {
 return [[self alloc]init];
 }

 //4.嚴(yán)謹(jǐn)
 -(id)copyWithZone:(NSZone *)zone
 {
 return _instance;
 }

 -(id)mutableCopyWithZone:(NSZone *)zone
 {
 return _instance;
 }

  • NSOpreation認(rèn)識學(xué)習(xí):

  • 使用方法:

    • NSInvocationOperation方法:
    1.封裝操作
     NSInvocationOperation *op1 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(download1) object:nil];
    2.開始操作
    [op1 start];
    
    • NSBlockOperation方法:
      //1.封裝操作
    NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"1---%@",[NSThread currentThread]);
    }];
     //追加操作
    //如果操作里面的任務(wù)數(shù)量大于一,那么會開子線程一起執(zhí)行
    [op3 addExecutionBlock:^{
        NSLog(@"4---%@",[NSThread currentThread]);
    }];
      //2.開始操作
      [op1 start];
    
    • 自定義NSOpreation子類
  • 多圖下載案例總結(jié):

  • 項目設(shè)計思路:框架搭建(XMGApp存放模型數(shù)據(jù))->解決圖片重復(fù)下載問題(內(nèi)存緩存->磁盤緩存)->界面運(yùn)行卡頓問題解決(將圖片下載等耗時操作放到子線程中)->隊列重復(fù)創(chuàng)建問題(懶加載隊列)->數(shù)據(jù)錯亂問題解決(將每次下載的任務(wù)都添加到內(nèi)存中,并在下一次下載的時候檢查內(nèi)存是否有相應(yīng)任務(wù))->圖片不顯示問題解決(刷新每個cell)->cell重復(fù)使用(清空設(shè)置完的圖片或者設(shè)置占位圖片)

  • 框架搭建:省略

  • 圖片重復(fù)下載問題解決:

    1.檢查內(nèi)存緩存中的圖片,并往內(nèi)存緩存中設(shè)置圖片
    UIImage *image = [self.images objectForKey:appM.icon];
    [self.images setObject:image forKey:appM.icon];
    
    2.檢查磁盤緩存中的圖片,并往磁盤緩存中設(shè)置圖片
     NSString *cachesPath =[NSSearchPathForDirectoriesInDomains(NSCachesDirectory,   NSUserDomainMask, YES) lastObject];
    //得到圖片的名稱
    NSString *filename = [appM.icon lastPathComponent];
    //拼接文件的全路徑
    NSString *fullPath = [cachesPath stringByAppendingPathComponent:filename];
    //去檢查磁盤緩存
    NSData *data = [NSData dataWithContentsOfFile:fullPath];
    //把圖片保存到磁盤緩存(圖片不能直接寫入file中,需要變?yōu)槎M(jìn)制數(shù)據(jù))
    [data writeToFile:fullPath atomically:YES];
    
  • 界面運(yùn)行卡頓問題解決:

```objc
將下載任務(wù)放到子線程中
NSBlockOperation dowbloadOperation = [NSBlockOperation blockOperationWithBlock:^{
  ......
            }];
[self.queue addOperation:dowbloadOperation];
```
  • 隊列重復(fù)創(chuàng)建問題解決:
```objc
-(NSOperationQueue *)queue

{
if (_queue == nil) {
_queue = [[NSOperationQueue alloc]init];
_queue.maxConcurrentOperationCount = 5;
}
return _queue;
}
```

  • 數(shù)據(jù)錯亂問題解決:
1.懶加載任務(wù)字典,存放任務(wù)
-(NSMutableDictionary *)operations
{
 if (_operations == nil) {
     _operations = [NSMutableDictionary dictionary];
 }
 return _operations;
}
2.檢查操作緩存
  NSBlockOperation *dowbloadOperation = [self.operations objectForKey:appM.icon];
3.添加操作到緩存中
  [self.operations setObject:dowbloadOperation forKey:appM.icon];
  • 圖片不顯示問題解決:
```objc
//設(shè)置圖片([tableView reloadData];刷新整個tableView cell.imageView.image = image;storyboard中的cell中imageView尺寸默認(rèn)為0)
[[NSOperationQueue mainQueue]addOperationWithBlock:^{
 //刷新指定的行
[tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationMiddle];
                }];
```
  • cell復(fù)用問題解決:
```objc
//清空圖片或者是設(shè)置占位圖片
 cell.imageView.image = [UIImage imageNamed:@"Snip20200808_172"];
```
  • 項目運(yùn)行報錯(超時或找不到圖片):
if (image == nil) {
     //把操作從操作緩存中移除
      [self.operations removeObjectForKey:appM.icon];
      return ;
   }
  • 內(nèi)存警告問題解決:
    -(void)didReceiveMemoryWarning
    

{
//移除內(nèi)存緩存
[self.images removeAllObjects];

//取消隊列中的操作
[self.queue cancelAllOperations];

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • NSThread 第一種:通過NSThread的對象方法 NSThread *thread = [[NSThrea...
    攻城獅GG閱讀 955評論 0 3
  • 在這篇文章中,我將為你整理一下 iOS 開發(fā)中幾種多線程方案,以及其使用方法和注意事項。當(dāng)然也會給出幾種多線程的案...
    張戰(zhàn)威ican閱讀 699評論 0 0
  • 進(jìn)程和線程 首先,在了解多線程之前要了解什么是進(jìn)程,什么是線程 什么是進(jìn)程呢?進(jìn)程是指在系統(tǒng)中正在運(yùn)行的一個應(yīng)用程...
    擱淺的青蛙閱讀 463評論 0 0
  • 前言: 第一次接觸多線程還是在寫android的時候,咋一看,覺得這玩意好難(面試必問);其實(shí)從字眼上看多線程分為...
    張無忌_閱讀 216評論 0 0
  • 2013年 ¥37900 2014年 ¥43300
    麥田牧羊者閱讀 137評論 0 0

友情鏈接更多精彩內(nèi)容