麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

多線程開(kāi)發(fā)之三GCD

2019-11-14 18:25:41
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

NSThread、NSOperation、GCD 總結(jié):

  1. 無(wú)論使用哪種方法進(jìn)行多線程開(kāi)發(fā),每個(gè)線程啟動(dòng)后并不一定立即執(zhí)行相應(yīng)的操作,具體什么時(shí)候由系統(tǒng)調(diào)度(CPU 空閑時(shí)就會(huì)執(zhí)行)

  2. 更新 UI 應(yīng)該在主線程(UI 線程)中進(jìn)行,并且推薦使用同步調(diào)用,常用的方法如下:

    - (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;

    - (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL) wait; //方法傳遞主線程[NSThread mainThread])

    [NSOperationQueue mainQueue] addOperationWithBlock:

    dispatch_sync(dispatch_get_main_queue(), ^{})

  3. NSThread 適合輕量級(jí)多線程開(kāi)發(fā),控制線程順序比較難,同時(shí)線程總數(shù)無(wú)法控制(每次創(chuàng)建并不能重用之前的線程,只能創(chuàng)建一個(gè)新的線程)

  4. 對(duì)于簡(jiǎn)單的多線程開(kāi)發(fā)建議使用 NSObject 的擴(kuò)展方法完成,而不必使用 NSThread

  5. 可以使用 NSThread 的 currentThread 方法取得當(dāng)前線程,使用 sleepForTimeInterval: 方法讓當(dāng)前線程掛起

  6. NSOperation 進(jìn)行多線程開(kāi)發(fā)可以控制線程總數(shù)及線程依賴關(guān)系

  7. 創(chuàng)建一個(gè) NSOperation 不應(yīng)該直接調(diào)用 start 方法(如果直接 start 則會(huì)在主線程中調(diào)用)而是應(yīng)該放到 NSOperationQueue 中啟動(dòng)

  8. 相比 NSInvocationOperation 推薦使用 NSBlockOperation,代碼簡(jiǎn)單,同時(shí)由于閉包性使他沒(méi)有傳參問(wèn)題

  9. NSOperation 是對(duì) GCD 面向?qū)ο蟮?OC 封裝。而 GCD 基于 C 語(yǔ)言開(kāi)發(fā),效率更高。建議如果任務(wù)之間有依賴關(guān)系或者想要監(jiān)聽(tīng)任務(wù)完成狀態(tài)的情況下優(yōu)先選擇 NSOperation,否則使用 GCD

  10. 在 GCD 中串行隊(duì)列中的任務(wù)被安排到一個(gè)單一線程執(zhí)行(不是主線程),可以方便地控制執(zhí)行順序;并發(fā)隊(duì)列在多個(gè)線程中執(zhí)行(前提是使用異步方法),順序控制相對(duì)復(fù)雜,但是更高效

  11. 在 GCD 中一個(gè)操作是多線程還是單線程執(zhí)行,取決于當(dāng)前隊(duì)列類型和執(zhí)行方法。只有隊(duì)列類型為并行隊(duì)列并且使用異步方法執(zhí)行時(shí)才能在多個(gè)線程中執(zhí)行(如果是并行隊(duì)列使用同步方法調(diào)用則會(huì)在主線程中執(zhí)行)

 

效果如下:

 

ViewController.h

1 #import <UIKit/UIKit.h>2 3 @interface ViewController : UITableViewController4 @PRoperty (copy, nonatomic) NSArray *arrSampleName;5 6 - (instancetype)initWithSampleNameArray:(NSArray *)arrSampleName;7 8 @end

ViewController.m

 1 #import "ViewController.h" 2 #import "FirstSampleViewController.h" 3 #import "SecondSampleViewController.h" 4  5 @interface ViewController () 6 - (void)layoutUI; 7 @end 8  9 @implementation ViewController10 - (void)viewDidLoad {11     [super viewDidLoad];12     13     [self layoutUI];14 }15 16 - (void)didReceiveMemoryWarning {17     [super didReceiveMemoryWarning];18     // Dispose of any resources that can be recreated.19 }20 21 - (instancetype)initWithSampleNameArray:(NSArray *)arrSampleName {22     if (self = [super initWithStyle:UITableViewStyleGrouped]) {23         self.navigationItem.title = @"多線程開(kāi)發(fā)之三 GCD";24         self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"返回首頁(yè)" style:UIBarButtonItemStylePlain target:nil action:nil];25         26         _arrSampleName = arrSampleName;27     }28     return self;29 }30 31 - (void)layoutUI {32 }33 34 #pragma mark - UITableViewController相關(guān)方法重寫35 - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {36     return 0.1;37 }38 39 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {40     return 1;41 }42 43 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {44     return [_arrSampleName count];45 }46 47 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {48     static NSString *cellIdentifier = @"cell";49     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];50     if (!cell) {51         cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];52     }53     cell.textLabel.text = _arrSampleName[indexPath.row];54     return cell;55 }56 57 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {58     switch (indexPath.row) {59         case 0: {60             FirstSampleViewController *firstSampleVC = [FirstSampleViewController new];61             [self.navigationController pushViewController:firstSampleVC animated:YES];62             break;63         }64         case 1: {65             SecondSampleViewController *secondSampleVC = [SecondSampleViewController new];66             [self.navigationController pushViewController:secondSampleVC animated:YES];67             break;68         }69         default:70             break;71     }72 }73 74 @end

UIImage+RescaleImage.h

 1 #import <UIKit/UIKit.h> 2  3 @interface UIImage (RescaleImage) 4 /** 5  *  根據(jù)寬高大小,獲取對(duì)應(yīng)的縮放圖片 6  * 7  *  @param size 寬高大小 8  * 9  *  @return 對(duì)應(yīng)的縮放圖片10  */11 - (UIImage *)rescaleImageToSize:(CGSize)size;12 13 @end 

UIImage+RescaleImage.m

 1 #import "UIImage+RescaleImage.h" 2  3 @implementation UIImage (RescaleImage) 4  5 - (UIImage *)rescaleImageToSize:(CGSize)size { 6     CGRect rect = CGRectMake(0.0, 0.0, size.width, size.height); 7      8     UIGraphicsBeginImageContext(rect.size); 9     [self drawInRect:rect];10     UIImage *imgScale = UIGraphicsGetImageFromCurrentImageContext();11     UIGraphicsEndImageContext();12     13     return imgScale;14 }15 16 @end

Common.h

1 #import <Foundation/Foundation.h>2 3 @interface Common : NSObject4 + (NSURL *)randomImageURL;5 6 @end 

Common.m

 1 #import "Common.h" 2  3 static NSArray *arrPartOfURL = nil; 4 @implementation Common 5  6 + (NSURL *)randomImageURL { 7     if (arrPartOfURL == nil) { 8         arrPartOfURL = @[ 9                          @"chronograph",10                          @"color",11                          @"modular",12                          @"utility",13                          @"mickey_mouse",14                          @"simple",15                          @"motion",16                          @"solar",17                          @"astronomy",18                          @"timer",19                          @"alarm",20                          @"world_clock"21                          ];22     }23     24     NSUInteger randomVal = (arc4random() % 12); //0-11的隨機(jī)數(shù)25     NSString *imageURLStr = [NSString stringWithFormat:@"http://images.apple.com/v/watch/e/timekeeping/images/%@_large.jpg", arrPartOfURL[randomVal]];26     return [NSURL URLWithString:imageURLStr];27 }28 29 @end 

FirstSampleViewController.h

1 #import <UIKit/UIKit.h>2 3 @interface FirstSampleViewController : UIViewController4 @property (assign, nonatomic) CGSize rescaleImageSize;5 6 @property (strong, nonatomic) IBOutlet UIImageView *imgV;7 @property (strong, nonatomic) IBOutlet UIButton *btnLoadImage;8 9 @end 

FirstSampleViewController.m

  1 #import "FirstSampleViewController.h"  2 #import "UIImage+RescaleImage.h"  3 #import "Common.h"  4   5 @interface FirstSampleViewController ()  6 - (void)layoutUI;  7 - (void)updateImage:(NSData *)imageData;  8 @end  9  10 @implementation FirstSampleViewController 11  12 - (void)viewDidLoad { 13     [super viewDidLoad]; 14      15     [self layoutUI]; 16 } 17  18 - (void)didReceiveMemoryWarning { 19     [super didReceiveMemoryWarning]; 20     // Dispose of any resources that can be recreated. 21 } 22  23 - (void)dealloc { 24     _imgV.image = nil; 25 } 26  27 - (void)layoutUI { 28     self.view.backgroundColor = [UIColor colorWithWhite:0.957 alpha:1.000]; 29      30     CGFloat width = [[UIScreen mainScreen] bounds].size.width; //bounds 返回整個(gè)屏幕大??;applicationFrame 返回去除狀態(tài)欄后的屏幕大小 31     CGFloat height = width * 243.0 / 221.0; 32     const CGFloat percentVal = 3.0 / 4.0; //以屏幕寬度的3/4比例顯示 33     _rescaleImageSize = CGSizeMake(width * percentVal, height * percentVal); 34      35     //NSString *path = [[NSBundle mainBundle] pathForResource:@"PictureNo@2x" ofType:@"png"]; 36     //_imgV.image = [UIImage imageWithContentsOfFile:path]; 37      38     _btnLoadImage.tintColor = [UIColor darkGrayColor]; 39     _btnLoadImage.layer.masksToBounds = YES; 40     _btnLoadImage.layer.cornerRadius = 10.0; 41     _btnLoadImage.layer.borderColor = [UIColor grayColor].CGColor; 42     _btnLoadImage.layer.borderWidth = 1.0; 43 } 44  45 - (void)updateImage:(NSData *)imageData { 46     UIImage *img = [UIImage imageWithData:imageData]; 47     _imgV.image = [img rescaleImageToSize:_rescaleImageSize]; 48 } 49  50 - (IBAction)loadImage:(id)sender { 51     /* 52      GCD(Grand Central Dispatch):中央調(diào)度 53      相比 NSThread 和 NSOperation 來(lái)說(shuō),他的顯著優(yōu)點(diǎn)是:對(duì)于多核運(yùn)算更加有效 54      1、GCD 的一個(gè)重要概念是隊(duì)列,他的核心理念:將多個(gè)任務(wù)添加到 dispatch queue(調(diào)度隊(duì)列)中,系統(tǒng)會(huì)為我們管理這些 dispath queue,為我們?cè)诙鄠€(gè)線程上分配并執(zhí)行任務(wù),我們不需要直接啟動(dòng)和管理后臺(tái)線程。 55      2、系統(tǒng)提供了許多預(yù)定義的 dispatch queue,包括可以保證始終在主線程上執(zhí)行工作的 dispatch queue。也可以創(chuàng)建自己的dispatch queue,而且可以創(chuàng)建任意多個(gè)。GCD的 dispatch queue 嚴(yán)格遵循 FIFO(先進(jìn)先出)原則,添加到 dispatch queue 的任務(wù)將始終按照加入 dispatch queue 的順序啟動(dòng)。 56      3、dispatch queue按先進(jìn)先出的順序,串行或并發(fā)地執(zhí)行任務(wù) 57      1> serial dispatch queue(串行調(diào)度隊(duì)列):一次只能執(zhí)行一個(gè)任務(wù),當(dāng)前任務(wù)完成后才開(kāi)始出列并啟動(dòng)下一個(gè)任務(wù) 58      2> concurrent dispatch queue(并發(fā)調(diào)度隊(duì)列):則盡可能多地啟動(dòng)任務(wù)并發(fā)執(zhí)行 59       60      同步和異步?jīng)Q定了要不要開(kāi)啟新的線程 61      同步:在當(dāng)前線程中執(zhí)行任務(wù),不具備開(kāi)啟新線程的能力(如果當(dāng)前線程是主線程的話,會(huì)造成線程阻塞,一般比較少用) 62      異步:在新的線程中執(zhí)行任務(wù),具備開(kāi)啟新線程的能力 63       64      串行和并發(fā)決定了任務(wù)的執(zhí)行方式 65      串行:一個(gè)任務(wù)執(zhí)行完畢后,再執(zhí)行下一個(gè)任務(wù) 66      并發(fā):多個(gè)任務(wù)并發(fā)(同時(shí))執(zhí)行 67      */ 68      69     /* 70      系統(tǒng)給每個(gè)應(yīng)用提供了四個(gè)全局并發(fā)隊(duì)列,整個(gè)應(yīng)用內(nèi)全局共享,他們的區(qū)別是通過(guò)「全局并發(fā)隊(duì)列優(yōu)先級(jí)」;優(yōu)先級(jí)越高,隊(duì)列越先被列入執(zhí)行計(jì)劃中 71      #define DISPATCH_QUEUE_PRIORITY_HIGH 2 72      #define DISPATCH_QUEUE_PRIORITY_DEFAULT 0 73      #define DISPATCH_QUEUE_PRIORITY_LOW (-2) 74      #define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN 75      */ 76      77     //全局并發(fā)隊(duì)列 78     dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 79      80     //自定義串行隊(duì)列;第二個(gè)參數(shù)為 NULL 或 DISPATCH_QUEUE_SERIAL 表示串行隊(duì)列,而為 DISPATCH_QUEUE_CONCURRENT 表示并發(fā)隊(duì)列,但一般用 dispatch_get_global_queue 方法獲取并發(fā)隊(duì)列 81     //dispatch_queue_t customSerialQueue = dispatch_queue_create("Custom Queue", NULL); 82      83     //主隊(duì)列;屬于串行隊(duì)列 84     dispatch_queue_t mainQueue = dispatch_get_main_queue(); 85      86      87     //方法一:自定義串行隊(duì)列同步:不會(huì)開(kāi)啟新線程、串行執(zhí)行任務(wù) 88 //    dispatch_sync(customSerialQueue, ^{ 89 //        NSLog(@"自定義串行隊(duì)列同步,線程:%@", [NSThread currentThread]); //所在的線程,這里就是在主線程 90 //        NSURL *url = [Common randomImageURL]; 91 //        NSData *data = [NSData dataWithContentsOfURL:url]; 92 //         93 //        dispatch_async(mainQueue, ^{ //主隊(duì)列異步(同步也一樣):不會(huì)開(kāi)啟新線程、串行執(zhí)行任務(wù) 94 //            NSLog(@"主隊(duì)列異步(同步也一樣),線程:%@", [NSThread currentThread]); //主隊(duì)列所對(duì)應(yīng)的主線程 95 //            [self updateImage:data]; 96 //        }); 97 //    }); 98      99     //方法二:自定義串行隊(duì)列異步:開(kāi)啟新線程、串行執(zhí)行任務(wù)100 //    dispatch_async(customSerialQueue, ^{101 //        NSLog(@"自定義串行隊(duì)列異步,線程:%@", [NSThread currentThread]); //開(kāi)啟的新線程102 //        NSURL *url = [Common randomImageURL];103 //        NSData *data = [NSData dataWithContentsOfURL:url];104 //        105 //        dispatch_async(mainQueue, ^{ //主隊(duì)列異步(同步也一樣):不會(huì)開(kāi)啟新線程、串行執(zhí)行任務(wù)106 //            NSLog(@"主隊(duì)列異步(同步也一樣),線程:%@", [NSThread currentThread]); //主隊(duì)列所對(duì)應(yīng)的主線程107 //            [self updateImage:data];108 //        });109 //    });110     111     112     //方法三:全局并發(fā)隊(duì)列同步:不會(huì)開(kāi)啟新線程、串行執(zhí)行任務(wù)113 //    dispatch_sync(globalQueue, ^{114 //        NSLog(@"全局并發(fā)隊(duì)列同步,線程:%@", [NSThread currentThread]); //所在的線程,這里就是在主線程115 //        NSURL *url = [Common randomImageURL];116 //        NSData *data = [NSData dataWithContentsOfURL:url];117 //        118 //        dispatch_async(mainQueue, ^{ //主隊(duì)列異步(同步也一樣):不會(huì)開(kāi)啟新線程、串行執(zhí)行任務(wù)119 //            NSLog(@"主隊(duì)列異步(同步也一樣),線程:%@", [NSThread currentThread]); //主隊(duì)列所對(duì)應(yīng)的主線程120 //            [self updateImage:data];121 //        });122 //    });123     124     125     //方法四:全局并發(fā)隊(duì)列異步:開(kāi)啟新線程、并發(fā)執(zhí)行任務(wù)126     dispatch_async(globalQueue, ^{127         NSLog(@"全局并發(fā)隊(duì)列異步,線程:%@", [NSThread currentThread]); //開(kāi)啟的新線程128         NSURL *url = [Common randomImageURL];129         NSData *data = [NSData dataWithContentsOfURL:url];130         131         dispatch_async(mainQueue, ^{ //主隊(duì)列異步(同步也一樣):不會(huì)開(kāi)啟新線程、串行執(zhí)行任務(wù)132             NSLog(@"主隊(duì)列異步(同步也一樣),線程:%@", [NSThread currentThread]); //主隊(duì)列所對(duì)應(yīng)的主線程133             [self updateImage:data];134         });135     });136 }137 138 @end 

FirstSampleViewController.xib

 1 <?xml version="1.0" encoding="UTF-8" standalone="no"?> 2 <document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="7706" systemVersion="14E46" targetRuntime="iOS.CocoaTouch" propertyaccessControl="none" useAutolayout="YES" useTraitCollections="YES"> 3     <dependencies> 4         <deployment identifier="iOS"/> 5         <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7703"/> 6     </dependencies> 7     <objects> 8         <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="FirstSampleViewController"> 9             <connections>10                 <outlet property="btnLoadImage" destination="sLs-f1-Gzc" id="kX8-J0-v0V"/>11                 <outlet property="imgV" destination="4Qp-uk-KAb" id="RM3-Ha-glh"/>12                 <outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/>13             </connections>14         </placeholder>15         <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>16         <view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="i5M-Pr-FkT">17             <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>18             <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>19             <subviews>20                 <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="PictureNo.png" translatesAutoresizingMaskIntoConstraints="NO" id="4Qp-uk-KAb">21                     <rect key="frame" x="205" y="225" width="190" height="150"/>22                     <constraints>23                         <constraint firstAttribute="height" constant="150" id="S/>24                         <constraint firstAttribute="height" constant="150" id="VwM-i1-atB"/>25                         <constraint firstAttribute="width" constant="190" id="mUh-Bu-tUd"/>26                         <constraint firstAttribute="width" constant="190" id="mdJ-1c-QFa"/>27                         <constraint firstAttribute="width" constant="190" id="sVS-bU-Ty9"/>28                         <constraint firstAttribute="height" constant="150" id="uMG-oN-J56"/>29                         <constraint firstAttribute="height" constant="150" id="vws-Qw-UrB"/>30                     </constraints>31                     <variation key="default">32                         <mask key="constraints">33                             <exclude reference="SIp-Wd-idU"/>34                             <exclude reference="VwM-i1-atB"/>35                             <exclude reference="mUh-Bu-tUd"/>36                             <exclude reference="mdJ-1c-QFa"/>37                             <exclude reference="sVS-bU-Ty9"/>38                             <exclude reference="uMG-oN-J56"/>39                             <exclude reference="vws-Qw-UrB"/>40                         </mask>41                     </variation>42                 </imageView>43                 <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="sLs-f1-Gzc">44                     <rect key="frame" x="230" y="500" width="140" height="50"/>45                     <constraints>46                         <constraint firstAttribute="width" constant="140" id="1jv-9K-mdH"/>47                         <constraint firstAttribute="height" constant="50" id="Q2w-vR-9ac"/>48                     </constraints>49                     <state key="normal" title="加載網(wǎng)絡(luò)圖片">50                         <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>51                     </state>52                     <connections>53                         <action selector="loadImage:" destination="-1" eventType="touchUpInside" id="fdy-Ln-5oS"/>54                     </connections>55                 </button>56             </subviews>57             <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>58             <constraints>59                 <constraint firstItem="4Qp-uk-KAb" firstAttribute="leading" secondItem="i5M-Pr-FkT" secondAttribute="leading" constant="205" id="2a2-mS-WFa"/>60                 <constraint firstItem="sLs-f1-Gzc" firstAttribute="top" secondItem="i5M-Pr-FkT" secondAttribute="top" id="ES4-wl-RBz"/>61                 <constraint firstItem="4Qp-uk-KAb" firstAttribute="centerY" secondItem="i5M-Pr-FkT" secondAttribute="centerY" id="MUJ-WA-sUf"/>62                 <constraint firstItem="4Qp-uk-KAb" firstAttribute="centerX" secondItem="sLs-f1-Gzc" secondAttribute="centerX" id="Q8a-1k-DzJ"/>63                 <constraint firstAttribute="bottom" secondItem="4Qp-uk-KAb" secondAttribute="bottom" constant="71" id="V0a-9y-Dwa"/>64                 <constraint firstAttribute="bottom" secondItem="sLs-f1-Gzc" secondAttribute="bottom" constant="50" id="VMG-CV-eeq"/>65                 <constraint firstItem="4Qp-uk-KAb" firstAttribute="top" secondItem="i5M-Pr-FkT" secondAttribute="top" constant="-71" id="gqW-Wq-4Zv"/>66                 <constraint firstItem="sLs-f1-Gzc" firstAttribute="centerX" secondItem="i5M-Pr-FkT" secondAttribute="centerX" id="kNf-6d-EJ8"/>67             </constraints>68             <variation key="default">69                 <mask key="constraints">70                     <exclude reference="2a2-mS-WFa"/>71                     <exclude reference="V0a-9y-Dwa"/>72                     <exclude reference="gqW-Wq-4Zv"/>73                     <exclude reference="ES4-wl-RBz"/>74                 </mask>75             </variation>76         </view>77     </objects>78     <resources>79         <image name="PictureNo.png" width="190" height="150"/>80     </resources>81 </document> 

SecondSampleViewController.h

SecondSampleViewController.m

  1 #import "SecondSampleViewController.h"  2 #import "UIImage+RescaleImage.h"  3 #import "Common.h"  4   5 #define kRowCount 4  6 #define kColumnCount 3  7 #define kCellSpacing 10.0  8   9 @interface SecondSampleViewController () 10 - (void)layoutUI; 11 - (void)updateImage:(NSData *)imageData withImageIndex:(NSInteger)imageIndex; 12 -(NSData *)requestData:(NSInteger)imageIndex; 13 - (void)loadImageFromNetwork:(NSInteger)imageIndex; 14 - (void)loadImageByDispatchAsync; 15 - (void)loadImageByDispatchApply; 16 - (void)loadImageByDispatchGroupAsync; 17 - (void)additionalInfo; 18 @end 19  20 @implementation SecondSampleViewController 21  22 - (void)viewDidLoad { 23     [super viewDidLoad]; 24      25     [self layoutUI]; 26 } 27  28 - (void)didReceiveMemoryWarning { 29     [super didReceiveMemoryWarning]; 30     // Dispose of any resources that can be recreated. 31 } 32  33 - (void)dealloc { 34     _mArrImageView = nil; 35 } 36  37 - (void)layoutUI { 38     self.view.backgroundColor = [UIColor colorWithWhite:0.957 alpha:1.000]; 39      40     CGFloat width = ([[UIScreen mainScreen] bounds].size.width - ((kColumnCount + 1) * kCellSpacing)) / kColumnCount; 41     _rescaleImageSize = CGSizeMake(width, width); 42      43     CGFloat heightOfStatusAndNav = 20.0 + 44.0; 44     NSString *path = [[NSBundle mainBundle] pathForResource:@"PictureNo@2x" ofType:@"png"]; 45     UIImage *img = [UIImage imageWithContentsOfFile:path]; 46     _mArrImageView = [NSMutableArray arrayWithCapacity:kRowCount * kColumnCount]; 47     //初始化多個(gè)圖片視圖 48     for (NSUInteger i=0; i<kRowCount; i++) { 49         for (NSUInteger j=0; j<kColumnCount; j++) { 50             UIImageView *imgV = [[UIImageView alloc] initWithFrame: 51                                  CGRectMake(_rescaleImageSize.width * j + kCellSpacing * (j+1), 52                                             _rescaleImageSize.height * i + kCellSpacing * (i+1) + heightOfStatusAndNav, 53                                             _rescaleImageSize.width, 54                                             _rescaleImageSize.height)]; 55             imgV.image = img; 56             [self.view addSubview:imgV]; 57             [_mArrImageView addObject:imgV]; 58         } 59     } 60      61     _btnLoadImage.tintColor = [UIColor darkGrayColor]; 62     _btnLoadImage.layer.masksToBounds = YES; 63     _btnLoadImage.layer.cornerRadius = 10.0; 64     _btnLoadImage.layer.borderColor = [UIColor grayColor].CGColor; 65     _btnLoadImage.layer.borderWidth = 1.0; 66 } 67  68 - (void)updateImage:(NSData *)imageData withImageIndex:(NSInteger)imageIndex { 69     UIImage *img = [UIImage imageWithData:imageData]; 70     UIImageView *imgVCurrent = _mArrImageView[imageIndex]; 71     imgVCurrent.image = [img rescaleImageToSize:_rescaleImageSize]; 72 } 73  74 -(NSData *)requestData:(NSInteger)imageIndex { 75     //對(duì)于多線程操作,建議把線程操作放到 @autoreleasepool 中 76     @autoreleasepool { 77         NSURL *url = [Common randomImageURL]; 78         NSData *data = [NSData dataWithContentsOfURL:url]; 79         return data; 80     } 81 } 82  83 - (void)loadImageFromNetwork:(NSInteger)imageIndex { 84     NSData *data = [self requestData:imageIndex]; 85      86     NSLog(@"Current thread:%@, imageIndex:%ld", [NSThread currentThread], (long)imageIndex); //dispatch_async、dispatch_apply、dispatch_group_async 的全局并發(fā)隊(duì)列,會(huì)開(kāi)啟多個(gè)新線程去執(zhí)行多個(gè)任務(wù);按系統(tǒng)管理,也可能存在一個(gè)線程執(zhí)行兩個(gè)任務(wù)的情況 87      88     dispatch_async(dispatch_get_main_queue(), ^{ //主隊(duì)列異步(同步也一樣):不會(huì)開(kāi)啟新線程、串行執(zhí)行任務(wù) 89         NSLog(@"主隊(duì)列異步(同步也一樣),線程:%@", [NSThread currentThread]); //主隊(duì)列所對(duì)應(yīng)的主線程 90         [self updateImage:data withImageIndex:imageIndex]; 91     }); 92 } 93  94 #pragma mark - 三種方法實(shí)現(xiàn)多線程并發(fā)執(zhí)行多個(gè)任務(wù),并且優(yōu)先加載最后一張圖片 95 - (void)loadImageByDispatchAsync { 96     dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //全局并發(fā)隊(duì)列 97      98     dispatch_async(globalQueue, ^{ 99         NSInteger len = kRowCount * kColumnCount - 1;100         101         NSLog(@"全局并發(fā)隊(duì)列異步,線程:%@", [NSThread currentThread]); //開(kāi)啟的新線程102         [self loadImageFromNetwork:len]; //優(yōu)先加載最后一張圖片103         104         for (NSUInteger i=0; i<len; i++) {105             dispatch_async(globalQueue, ^{106                 [self loadImageFromNetwork:i];107             });108         }109     });110 }111 112 - (void)loadImageByDispatchApply {113     dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //全局并發(fā)隊(duì)列114     115     //使用 dispatch_async,全局并發(fā)隊(duì)列異步:開(kāi)啟新線程、并發(fā)執(zhí)行任務(wù);此時(shí)會(huì)并發(fā)無(wú)序地逐個(gè)圖片加載并顯示出來(lái)116     //PS:如果使用 dispatch_sync,全局并發(fā)隊(duì)列同步:不會(huì)開(kāi)啟新線程、串行執(zhí)行任務(wù);此時(shí)會(huì)等到全部圖片加載完才全部顯示出來(lái)117     dispatch_async(globalQueue, ^{118         size_t len = kRowCount * kColumnCount - 1;119         120         NSLog(@"全局并發(fā)隊(duì)列異步,線程:%@", [NSThread currentThread]); //開(kāi)啟的新線程121         [self loadImageFromNetwork:len]; //優(yōu)先加載最后一張圖片122         123         //使用 dispatch_apply 或 dispatch_apply_f 來(lái)循環(huán)迭代執(zhí)行任務(wù);前提是迭代的任務(wù)相互獨(dú)立,而且任務(wù)執(zhí)行順序是無(wú)關(guān)緊要的;124         //他每次循環(huán)迭代會(huì)將指定的任務(wù)提交到 queue,queue 會(huì)開(kāi)啟多個(gè)新線程(線程會(huì)盡量復(fù)用,線程更少,系統(tǒng)多線程之間切換調(diào)度更快)去執(zhí)行多個(gè)任務(wù),執(zhí)行順序是不會(huì)像 for 循環(huán)那樣有序執(zhí)行;125         //但是他像 for 循環(huán)一樣會(huì)在所有任務(wù)循環(huán)迭代執(zhí)行完后才返回,會(huì)阻塞當(dāng)前線程,所以只用于并發(fā)隊(duì)列。如果用于串行隊(duì)列,會(huì)造成死鎖,無(wú)法正常執(zhí)行126         dispatch_apply(len, globalQueue, ^(size_t i) {127             [self loadImageFromNetwork:i];128         });129     });130 }131 132 - (void)loadImageByDispatchGroupAsync {133     dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //全局并發(fā)隊(duì)列134     135     //使用 dispatch_async,全局并發(fā)隊(duì)列異步:開(kāi)啟新線程、并發(fā)執(zhí)行任務(wù);此時(shí)會(huì)并發(fā)無(wú)序地逐個(gè)圖片加載并顯示出來(lái)136     //PS:如果使用 dispatch_sync,全局并發(fā)隊(duì)列同步:不會(huì)開(kāi)啟新線程、串行執(zhí)行任務(wù);此時(shí)會(huì)等到全部圖片加載完才全部顯示出來(lái)137     dispatch_async(globalQueue, ^{138         NSInteger len = kRowCount * kColumnCount - 1;139         140         NSLog(@"全局并發(fā)隊(duì)列異步,線程:%@", [NSThread currentThread]); //開(kāi)啟的新線程141         [self loadImageFromNetwork:len]; //優(yōu)先加載最后一張圖片142         143         dispatch_group_t group = dispatch_group_create(); //自定義組144         for (NSUInteger i=0; i<len; i++) {145              //把一系列任務(wù)提交到隊(duì)列中,并統(tǒng)一關(guān)聯(lián)到自定義組中;這樣并發(fā)全部執(zhí)行完畢后,能通過(guò) dispatch_group_notify 進(jìn)行后續(xù)處理146             dispatch_group_async(group, globalQueue, ^{147                 [self loadImageFromNetwork:i];148             });149         }150         151         //自定義組通知;會(huì)根據(jù)隊(duì)列類型決定是否開(kāi)啟新線程;如果是并發(fā)隊(duì)列就會(huì)開(kāi)啟新線程(實(shí)際上是:復(fù)用自定義組執(zhí)行最后一個(gè)任務(wù)的對(duì)應(yīng)線程),否則是串行隊(duì)列就不會(huì)152         dispatch_group_notify(group, dispatch_get_main_queue(), ^{153             NSLog(@"自定義組通知,線程:%@", [NSThread currentThread]);154             NSLog(@"全部的 dispatch_group_async 任務(wù)執(zhí)行完畢后,做一些事情,只執(zhí)行一次");155         });156     });157 }158 159 - (void)additionalInfo {160     //dispatch_suspend(queue); //掛起隊(duì)列方法;當(dāng)前正在執(zhí)行的任務(wù)不會(huì)停下來(lái),只是不再繼續(xù)執(zhí)行未啟動(dòng)的任務(wù)161     //dispatch_resume(queue); //恢復(fù)隊(duì)列方法;確保他跟 dispatch_suspend 成對(duì)調(diào)用162     163     //單次執(zhí)行任務(wù)方法;方法是線程安全的164     static dispatch_once_t onceToken;165     dispatch_once(&onceToken, ^{166         NSLog(@"dispatch_once:?jiǎn)未螆?zhí)行任務(wù);只會(huì)執(zhí)行一次,重復(fù)調(diào)用方法也不會(huì)重復(fù)執(zhí)行(可用于應(yīng)用程序中初始化全局?jǐn)?shù)據(jù)的情況,例如:?jiǎn)卫J剑?/span>");167     });168     169     //類似 - (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay 的延時(shí)執(zhí)行方法170     dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{171         NSLog(@"dispatch_after:延時(shí)執(zhí)行任務(wù),這里2.0秒后做一些事情");172     });173 }174 175 - (IBAction)loadImage:(id)sender {176     //三種方法實(shí)現(xiàn)多線程并發(fā)執(zhí)行多個(gè)任務(wù),并且優(yōu)先加載最后一張圖片177     //方法一:dispatch_async178     //[self loadImageByDispatchAsync];179     180     //方法二:dispatch_apply181     //[self loadImageByDispatchApply];182     183     //方法三:dispatch_group_async184     [self loadImageByDispatchGroupAsync];185     186     187     //附加信息188     [self additionalInfo];189 }190 191 @end 

SecondSampleViewController.xib

 1 <?xml version="1.0" encoding="UTF-8" standalone="no"?> 2 <document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="7706" systemVersion="14E46" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES"> 3     <dependencies> 4         <deployment identifier="iOS"/> 5         <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7703"/> 6     </dependencies> 7     <objects> 8         <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="SecondSampleViewController"> 9             <connections>10                 <outlet property="btnLoadImage" destination="F5h-ZI-gGL" id="I40-e2-bAa"/>11                 <outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/>12             </connections>13         </placeholder>14         <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>15         <view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="i5M-Pr-FkT">16             <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>17             <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>18             <subviews>19                 <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="F5h-ZI-gGL">20                     <rect key="frame" x="230" y="530" width="140" height="50"/>21                     <constraints>22                         <constraint firstAttribute="height" constant="50" id="HWd-Xc-Wk7"/>23                         <constraint firstAttribute="width" constant="140" id="vrH-qE-PNK"/>24                     </constraints>25                     <state key="normal" title="加載網(wǎng)絡(luò)圖片">26                         <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>27                     </state>28                     <connections>29                         <action selector="loadImage:" destination="-1" eventType="touchUpInside" id="Hgw-q8-lHy"/>30                     </connections>31                 </button>32             </subviews>33             <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>34             <constraints>35                 <constraint firstAttribute="bottom" secondItem="F5h-ZI-gGL" secondAttribute="bottom" constant="20" id="jPY-fY-9XJ"/>36                 <constraint firstAttribute="centerX" secondItem="F5h-ZI-gGL" secondAttribute="centerX" id="rH1-sV-pST"/>37             </constraints>38         </view>39     </objects>40 </document> 

AppDelegate.h

AppDelegate.m

輸出結(jié)果:

方法三:dispatch_group_async

 1 2015-08-30 17:19:44.168 GCDDemo[4776:70114] 全局并發(fā)隊(duì)列異步,線程:<NSThread: 0x7f9511c7a920>{number = 4, name = (null)} 2 2015-08-30 17:19:44.168 GCDDemo[4776:70265] dispatch_once:?jiǎn)未螆?zhí)行任務(wù);只會(huì)執(zhí)行一次,重復(fù)調(diào)用方法也不會(huì)重復(fù)執(zhí)行(可用于應(yīng)用程序中初始化全局?jǐn)?shù)據(jù)的情況,例如:?jiǎn)卫J剑?/span> 3 2015-08-30 17:19:44.229 GCDDemo[4776:70265] Current thread:<NSThread: 0x7f9511c7a920>{number = 4, name = (null)}, imageIndex:11 4 2015-08-30 17:19:44.230 GCDDemo[4776:70114] 主隊(duì)列異步(同步也一樣),線程:<NSThread: 0x7f9511d0a9a0>{number = 1, name = main} 5 2015-08-30 17:19:44.283 GCDDemo[4776:70265] Current thread:<NSThread: 0x7f9511c7a920>{number = 4, name = (null)}, imageIndex:0 6 2015-08-30 17:19:44.283 GCDDemo[4776:70114] 主隊(duì)列異步(同步也一樣),線程:<NSThread: 0x7f9511d0a9a0>{number = 1, name = main} 7 2015-08-30 17:19:44.301 GCDDemo[4776:70248] Current thread:<NSThread: 0x7f9511f2b3f0>{number = 2, name = (null)}, imageIndex:1 8 2015-08-30 17:19:44.301 GCDDemo[4776:70114] 主隊(duì)列異步(同步也一樣),線程:<NSThread: 0x7f9511d0a9a0>{number = 1, name = main} 9 2015-08-30 17:19:44.516 GCDDemo[4776:70269] Current thread:<NSThread: 0x7f9511ef52f0>{number = 5, name = (null)}, imageIndex:210 2015-08-30 17:19:44.516 GCDDemo[4776:70114] 主隊(duì)列異步(同步也一樣),線程:<NSThread: 0x7f9511d0a9a0>{number = 1, name = main}11 2015-08-30 17:19:44.887 GCDDemo[4776:70241] Current thread:<NSThread: 0x7f9511d94230>{number = 6, name = (null)}, imageIndex:612 2015-08-30 17:19:44.888 GCDDemo[4776:70114] 主隊(duì)列異步(同步也一樣),線程:<NSThread: 0x7f9511d0a9a0>{number = 1, name = main}13 2015-08-30 17:19:44.999 GCDDemo[4776:70299] Current thread:<NSThread: 0x7f9511d93d40>{number = 7, name = (null)}, imageIndex:314 2015-08-30 17:19:44.999 GCDDemo[4776:70114] 主隊(duì)列異步(同步也一樣),線程:<NSThread: 0x7f9511d0a9a0>{number = 1, name = main}15 2015-08-30 17:19:45.152 GCDDemo[4776:70301] Current thread:<NSThread: 0x7f9511d78f90>{number = 8, name = (null)}, imageIndex:516 2015-08-30 17:19:45.152 GCDDemo[4776:70114] 主隊(duì)列異步(同步也一樣),線程:<NSThread: 0x7f9511d0a9a0>{number = 1, name = main}17 2015-08-30 17:19:45.190 GCDDemo[4776:70300] Current thread:<NSThread: 0x7f9511ef0340>{number = 9, name = (null)}, imageIndex:418 2015-08-30 17:19:45.190 GCDDemo[4776:70114] 主隊(duì)列異步(同步也一樣),線程:<NSThread: 0x7f9511d0a9a0>{number = 1, name = main}19 2015-08-30 17:19:45.240 GCDDemo[4776:70304] Current thread:<NSThread: 0x7f9511d8e9d0>{number = 10, name = (null)}, imageIndex:820 2015-08-30 17:19:45.240 GCDDemo[4776:70114] 主隊(duì)列異步(同步也一樣),線程:<NSThread: 0x7f9511d0a9a0>{number = 1, name = main}21 2015-08-30 17:19:45.314 GCDDemo[4776:70305] Current thread:<NSThread: 0x7f9511ecd030>{number = 11, name = (null)}, imageIndex:1022 2015-08-30 17:19:45.314 GCDDemo[4776:70114] 主隊(duì)列異步(同步也一樣),線程:<NSThread: 0x7f9511d0a9a0>{number = 1, name = main}23 2015-08-30 17:19:45.443 GCDDemo[4776:70302] Current thread:<NSThread: 0x7f9511d8fc50>{number = 12, name = (null)}, imageIndex:724 2015-08-30 17:19:45.443 GCDDemo[4776:70114] 主隊(duì)列異步(同步也一樣),線程:<NSThread: 0x7f9511d0a9a0>{number = 1, name = main}25 2015-08-30 17:19:45.615 GCDDemo[4776:70303] Current thread:<NSThread: 0x7f9511d91740>{number = 13, name = (null)}, imageIndex:926 2015-08-30 17:19:45.615 GCDDemo[4776:70114] 主隊(duì)列異步(同步也一樣),線程:<NSThread: 0x7f9511d0a9a0>{number = 1, name = main}27 2015-08-30 17:19:45.620 GCDDemo[4776:70114] 自定義組通知,線程:<NSThread: 0x7f9511d0a9a0>{number = 1, name = main}28 2015-08-30 17:19:45.620 GCDDemo[4776:70114] 全部的 dispatch_group_async 任務(wù)執(zhí)行完畢后,做一些事情,只執(zhí)行一次29 2015-08-30 17:19:46.360 GCDDemo[4776:70114] dispatch_after:延時(shí)執(zhí)行任務(wù),這里2.0秒后做一些事情 

方法一:dispatch_async

 1 2015-08-30 17:15:08.490 GCDDemo[4668:66939] 全局并發(fā)隊(duì)列異步,線程:<NSThread: 0x7fc5be00c810>{number = 2, name = (null)} 2 2015-08-30 17:15:08.490 GCDDemo[4668:66894] dispatch_once:?jiǎn)未螆?zhí)行任務(wù);只會(huì)執(zhí)行一次,重復(fù)調(diào)用方法也不會(huì)重復(fù)執(zhí)行(可用于應(yīng)用程序中初始化全局?jǐn)?shù)據(jù)的情況,例如:?jiǎn)卫J剑?/span> 3 2015-08-30 17:15:08.862 GCDDemo[4668:66939] Current thread:<NSThread: 0x7fc5be00c810>{number = 2, name = (null)}, imageIndex:11 4 2015-08-30 17:15:08.862 GCDDemo[4668:66894] 主隊(duì)列異步(同步也一樣),線程:<NSThread: 0x7fc5bbe280d0>{number = 1, name = main} 5 2015-08-30 17:15:09.062 GCDDemo[4668:66981] Current thread:<NSThread: 0x7fc5be05ac90>{number = 4, name = (null)}, imageIndex:3 6 2015-08-30 17:15:09.062 GCDDemo[4668:66894] 主隊(duì)列異步(同步也一樣),線程:<NSThread: 0x7fc5bbe280d0>{number = 1, name = main} 7 2015-08-30 17:15:09.066 GCDDemo[4668:66939] Current thread:<NSThread: 0x7fc5be00c810>{number = 2, name = (null)}, imageIndex:0 8 2015-08-30 17:15:09.067 GCDDemo[4668:66894] 主隊(duì)列異步(同步也一樣),線程:<NSThread: 0x7fc5bbe280d0>{number = 1, name = main} 9 2015-08-30 17:15:09.323 GCDDemo[4668:66941] Current thread:<NSThread: 0x7fc5bbf60040>{number = 5, name = (null)}, imageIndex:210 2015-08-30 17:15:09.323 GCDDemo[4668:66894] 主隊(duì)列異步(同步也一樣),線程:<NSThread: 0x7fc5bbe280d0>{number = 1, name = main}11 2015-08-30 17:15:09.323 GCDDemo[4668:66940] Current thread:<NSThread: 0x7fc5be05bf50>{number = 6, name = (null)}, imageIndex:112 2015-08-30 17:15:09.324 GCDDemo[4668:66942] Current thread:<NSThread: 0x7fc5bbd05bf0>{number = 7, name = (null)}, imageIndex:413 2015-08-30 17:15:09.327 GCDDemo[4668:66894] 主隊(duì)列異步(同步也一樣),線程:<NSThread: 0x7fc5bbe280d0>{number = 1, name = main}14 2015-08-30 17:15:09.330 GCDDemo[4668:66894] 主隊(duì)列異步(同步也一樣),線程:<NSThread: 0x7fc5bbe280d0>{number = 1, name = main}15 2015-08-30 17:15:09.486 GCDDemo[4668:66991] Current thread:<NSThread: 0x7fc5bbd1f880>{number = 8, name = (null)}, imageIndex:716 2015-08-30 17:15:09.486 GCDDemo[4668:66894] 主隊(duì)列異步(同步也一樣),線程:<NSThread: 0x7fc5bbe280d0>{number = 1, name = main}17 2015-08-30 17:15:10.156 GCDDemo[4668:66988] Current thread:<NSThread: 0x7fc5be05ae70>{number = 9, name = (null)}, imageIndex:518 2015-08-30 17:15:10.156 GCDDemo[4668:66894] 主隊(duì)列異步(同步也一樣),線程:<NSThread: 0x7fc5bbe280d0>{number = 1, name = main}19 2015-08-30 17:15:10.208 GCDDemo[4668:66990] Current thread:<NSThread: 0x7fc5bbd26b00>{number = 10, name = (null)}, imageIndex:620 2015-08-30 17:15:10.209 GCDDemo[4668:66894] 主隊(duì)列異步(同步也一樣),線程:<NSThread: 0x7fc5bbe280d0>{number = 1, name = main}21 2015-08-30 17:15:10.239 GCDDemo[4668:66992] Current thread:<NSThread: 0x7fc5bbe9ff30>{number = 11, name = (null)}, imageIndex:822 2015-08-30 17:15:10.239 GCDDemo[4668:66894] 主隊(duì)列異步(同步也一樣),線程:<NSThread: 0x7fc5bbe280d0>{number = 1, name = main}23 2015-08-30 17:15:10.491 GCDDemo[4668:66894] dispatch_after:延時(shí)執(zhí)行任務(wù),這里2.0秒后做一些事情24 2015-08-30 17:15:10.838 GCDDemo[4668:66993] Current thread:<NSThread: 0x7fc5bbea3940>{number = 12, name = (null)}, imageIndex:925 2015-08-30 17:15:10.838 GCDDemo[4668:66894] 主隊(duì)列異步(同步也一樣),線程:<NSThread: 0x7fc5bbe280d0>{number = 1, name = main}26 2015-08-30 17:15:11.489 GCDDemo[4668:66989] Current thread:<NSThread: 0x7fc5bbea4dd0>{number = 13, name = (null)}, imageIndex:1027 2015-08-30 17:15:11.490 GCDDemo[4668:66894] 主隊(duì)列異步(同步也一樣),線程:<NSThread: 0x7fc5bbe280d0>{number = 1, name = main} 

方法二:dispatch_apply

 1 2015-08-30 17:15:50.873 GCDDemo[4694:67547] 全局并發(fā)隊(duì)列異步,線程:<NSThread: 0x7fe57149bb60>{number = 2, name = (null)} 2 2015-08-30 17:15:50.873 GCDDemo[4694:67503] dispatch_once:?jiǎn)未螆?zhí)行任務(wù);只會(huì)執(zhí)行一次,重復(fù)調(diào)用方法也不會(huì)重復(fù)執(zhí)行(可用于應(yīng)用程序中初始化全局?jǐn)?shù)據(jù)的情況,例如:?jiǎn)卫J剑?/span> 3 2015-08-30 17:15:50.973 GCDDemo[4694:67547] Current thread:<NSThread: 0x7fe57149bb60>{number = 2, name = (null)}, imageIndex:11 4 2015-08-30 17:15:50.974 GCDDemo[4694:67503] 主隊(duì)列異步(同步也一樣),線程:<NSThread: 0x7fe571428b10>{number = 1, name = main} 5 2015-08-30 17:15:51.018 GCDDemo[4694:67546] Current thread:<NSThread: 0x7fe5714f8490>{number = 4, name = (null)}, imageIndex:1 6 2015-08-30 17:15:51.018 GCDDemo[4694:67503] 主隊(duì)列異步(同步也一樣),線程:<NSThread: 0x7fe571428b10>{number = 1, name = main} 7 2015-08-30 17:15:51.078 GCDDemo[4694:67546] Current thread:<NSThread: 0x7fe5714f8490>{number = 4, name = (null)}, imageIndex:4 8 2015-08-30 17:15:51.078 GCDDemo[4694:67503] 主隊(duì)列異步(同步也一樣),線程:<NSThread: 0x7fe571428b10>{number = 1, name = main} 9 2015-08-30 17:15:51.087 GCDDemo[4694:67562] Current thread:<NSThread: 0x7fe5717bd740>{number = 5, name = (null)}, imageIndex:210 2015-08-30 17:15:51.087 GCDDemo[4694:67503] 主隊(duì)列異步(同步也一樣),線程:<NSThread: 0x7fe571428b10>{number = 1, name = main}11 2015-08-30 17:15:51.200 GCDDemo[4694:67547] Current thread:<NSThread: 0x7fe57149bb60>{number = 2, name = (null)}, imageIndex:012 2015-08-30 17:15:51.200 GCDDemo[4694:67503] 主隊(duì)列異步(同步也一樣),線程:<NSThread: 0x7fe571428b10>{number = 1, name = main}13 2015-08-30 17:15:51.271 GCDDemo[4694:67562] Current thread:<NSThread: 0x7fe5717bd740>{number = 5, name = (null)}, imageIndex:614 2015-08-30 17:15:51.271 GCDDemo[4694:67503] 主隊(duì)列異步(同步也一樣),線程:<NSThread: 0x7fe571428b10>{number = 1, name = main}15 2015-08-30 17:15:51.628 GCDDemo[4694:67549] Current thread:<NSThread: 0x7fe57152d910>{number = 6, name = (null)}, imageIndex:316 2015-08-30 17:15:51.628 GCDDemo[4694:67503] 主隊(duì)列異步(同步也一樣),線程:<NSThread: 0x7fe571428b10>{number = 1, name = main}17 2015-08-30 17:15:51.701 GCDDemo[4694:67546] Current thread:<NSThread: 0x7fe5714f8490>{number = 4, name = (null)}, imageIndex:518 2015-08-30 17:15:51.701 GCDDemo[4694:67503] 主隊(duì)列異步(同步也一樣),線程:<NSThread: 0x7fe571428b10>{number = 1, name = main}19 2015-08-30 17:15:51.800 GCDDemo[4694:67547] Current thread:<NSThread: 0x7fe57149bb60>{number = 2, name = (null)}, imageIndex:720 2015-08-30 17:15:51.800 GCDDemo[4694:67503] 主隊(duì)列異步(同步也一樣),線程:<NSThread: 0x7fe571428b10>{number = 1, name = main}21 2015-08-30 17:15:52.063 GCDDemo[4694:67549] Current thread:<NSThread: 0x7fe57152d910>{number = 6, name = (null)}, imageIndex:922 2015-08-30 17:15:52.064 GCDDemo[4694:67503] 主隊(duì)列異步(同步也一樣),線程:<NSThread: 0x7fe571428b10>{number = 1, name = main}23 2015-08-30 17:15:52.109 GCDDemo[4694:67562] Current thread:<NSThread: 0x7fe5717bd740>{number = 5, name = (null)}, imageIndex:824 2015-08-30 17:15:52.110 GCDDemo[4694:67503] 主隊(duì)列異步(同步也一樣),線程:<NSThread: 0x7fe571428b10>{number = 1, name = main}25 2015-08-30 17:15:52.295 GCDDemo[4694:67546] Current thread:<NSThread: 0x7fe5714f8490>{number = 4, name = (null)}, imageIndex:1026 2015-08-30 17:15:52.295 GCDDemo[4694:67503] 主隊(duì)列異步(同步也一樣),線程:<NSThread: 0x7fe571428b10>{number = 1, name = main}27 2015-08-30 17:15:52.874 GCDDemo[4694:67503] dispatch_after:延時(shí)執(zhí)行任務(wù),這里2.0秒后做一些事情

 


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 国产日韩在线观看一区 | 中文字幕爱爱视频 | 国产午夜亚洲精品午夜鲁丝片 | 一区二区三区日韩电影 | 特级黄色小说 | 午夜精品老牛av一区二区三区 | 免费黄网站在线播放 | 日日操夜夜操视频 | 国产精品视频自拍 | 97伦理 | 国产精品成人久久 | 成人在线观看地址 | 久草在线资源福利站 | 免费观看一区二区三区视频 | 欧美国产日韩在线观看成人 | 粉嫩av一区二区三区四区在线观看 | 久久男人的天堂 | 4p嗯啊巨肉寝室调教男男视频 | 国产毛片在线看 | 国产亚洲精品视频中文字幕 | 免费观看一区二区三区 | 成人毛片免费视频 | 手机视频在线播放 | 久色免费视频 | 色婷婷一区二区三区 | avav在线播放 | 国产激情视频在线 | 日本不卡一区二区在线观看 | 深夜福利视频免费观看 | av在线免费看网址 | 久久久一区二区精品 | 欧美精品成人一区二区三区四区 | 日本羞羞影院 | 黄色aaa视频| 最新中文在线视频 | 91精品国产777在线观看 | 欧美十区| 国产一区二区三区高清 | 日韩黄色片在线观看 | 亚洲最大av网站 | 男人午夜小视频 |