你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> IOS開發(62)之GCD上異步執行非UI任務

IOS開發(62)之GCD上異步執行非UI任務

編輯:IOS開發綜合

1 前言


如果想要在 GCD 的幫助下能夠異步執行 Non-UI 相關任務。在主隊列、串行隊列和並發隊列上異步執行代碼塊才能見識到 GCD 的真正實力。

要在分派隊列上執行異步任務,你必須使用下面這些函數中的其中一個:

 

dispatch_async


為了異步執行向分派隊列提交一個 Block Object(2 個都通過函數指定);

eg:dispatch_sync(concurrentQueue, printFrom1To1000);


dispatch_async_f


為了異步執行向分派隊列提交一個 C 函數和一個上下文引用(3 項通過函數指定) 。

eg:dispatch_sync_f(concurrentQueue,NULL,printFrom1To1000);

 

2 代碼實例

這節代碼有點多,所以分了兩個工程

First:ZYViewController.m

 

[plain]  - (void) viewDidAppear:(BOOL)paramAnimated{ 
    //新建一個隊列 
    dispatch_queue_t concurrentQueue =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
    //執行concurrentQueue隊列 
    dispatch_async(concurrentQueue, ^{ 
        __block UIImage *image = nil; 
        dispatch_sync(concurrentQueue, ^{ 
            /*下載圖片*/ 
            /* 聲明圖片的路徑*/ 
            NSString *urlAsString = @"http://up.2cto.com/2013/0519/20130519101223949.jpg"; 
            //轉換為NSURL對象 
            NSURL *url = [NSURL URLWithString:urlAsString]; NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url]; 
            //聲明NSError對象:一個NSError對象封裝錯誤信息更豐富、更具可擴展性可以只使用一個錯誤代碼和錯誤字符串。 
            NSError *downloadError = nil; 
            //獲得對應的Url返回的數據(這裡是一個圖片的數據) 
            NSData *imageData = [NSURLConnection 
                                 sendSynchronousRequest:urlRequest returningResponse:nil error:&downloadError]; 
            if (downloadError == nil &&imageData != nil){ 
                //將NSData轉換為圖片 
                image = [UIImage imageWithData:imageData]; /* We have the image. We can use it now */ 
            } 
            else if (downloadError != nil){ 
                NSLog(@"Error happened = %@", downloadError); 
            }else{ 
                NSLog(@"No data could get downloaded from the URL."); 
            } 
        }); 
        dispatch_sync(dispatch_get_main_queue(), ^{ 
            /* 在主線程裡面顯示圖片*/ 
            if (image != nil){ 
                /* 穿件UIImageView視圖 */ 
                UIImageView *imageView = [[UIImageView alloc] 
                                          initWithFrame:self.view.bounds]; 
                /* 設置Image */ 
                [imageView setImage:image]; 
                /* 內容適應視圖的大小通過保持長寬比*/ 
                [imageView setContentMode:UIViewContentModeScaleAspectFit]; 
                /* 想Controller View添加圖像視圖 */ 
                [self.view addSubview:imageView]; 
            } else { 
                NSLog(@"Image isn't downloaded. Nothing to display."); 
            } }); 
    }); 

- (void) viewDidAppear:(BOOL)paramAnimated{
    //新建一個隊列
    dispatch_queue_t concurrentQueue =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    //執行concurrentQueue隊列
    dispatch_async(concurrentQueue, ^{
        __block UIImage *image = nil;
        dispatch_sync(concurrentQueue, ^{
            /*下載圖片*/
            /* 聲明圖片的路徑*/
            NSString *urlAsString = @"http://up.2cto.com/2013/0519/20130519101223949.jpg";
            //轉換為NSURL對象
            NSURL *url = [NSURL URLWithString:urlAsString]; NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
            //聲明NSError對象:一個NSError對象封裝錯誤信息更豐富、更具可擴展性可以只使用一個錯誤代碼和錯誤字符串。
            NSError *downloadError = nil;
            //獲得對應的Url返回的數據(這裡是一個圖片的數據)
            NSData *imageData = [NSURLConnection
                                 sendSynchronousRequest:urlRequest returningResponse:nil error:&downloadError];
            if (downloadError == nil &&imageData != nil){
                //將NSData轉換為圖片
                image = [UIImage imageWithData:imageData]; /* We have the image. We can use it now */
            }
            else if (downloadError != nil){
                NSLog(@"Error happened = %@", downloadError);
            }else{
                NSLog(@"No data could get downloaded from the URL.");
            }
        });
        dispatch_sync(dispatch_get_main_queue(), ^{
            /* 在主線程裡面顯示圖片*/
            if (image != nil){
                /* 穿件UIImageView視圖 */
                UIImageView *imageView = [[UIImageView alloc]
                                          initWithFrame:self.view.bounds];
                /* 設置Image */
                [imageView setImage:image];
                /* 內容適應視圖的大小通過保持長寬比*/
                [imageView setContentMode:UIViewContentModeScaleAspectFit];
                /* 想Controller View添加圖像視圖 */
                [self.view addSubview:imageView];
            } else {
                NSLog(@"Image isn't downloaded. Nothing to display.");
            } });
    });
}
運行結果

 \
 


Second:

ZYViewController.h

 

[plain]  #import <UIKit/UIKit.h> 
 
@interface ZYViewController : UIViewController 
 
@property(nonatomic,strong) UILabel *myLabel; 
 
@end 

#import <UIKit/UIKit.h>

@interface ZYViewController : UIViewController

@property(nonatomic,strong) UILabel *myLabel;

@end
ZYViewController.m


[plain]  @synthesize myLabel; 
 
- (void)viewDidLoad 

    [super viewDidLoad]; 
    //聲明一個隊列 
    dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
    /* 
     如果我們還沒有保存1000個隨機數在磁盤上,下面的隊列就用來生成這個文件並且用一個Array存放在磁盤上 
     */ 
    dispatch_async(concurrentQueue, ^{ 
        NSUInteger numberOfValuesRequired = 10000; 
        //判斷文件是否存在 
        if ([self hasFileAlreadyBeenCreated]== NO){ 
            dispatch_sync(concurrentQueue, ^{ 
                //聲明一個可變數組用來存放數值 
                NSMutableArray *arrayOfRandomNumbers =[[NSMutableArray alloc] initWithCapacity:numberOfValuesRequired]; 
                NSUInteger counter = 0; 
                for (counter = 0;counter < numberOfValuesRequired;counter++){ 
                    //獲得隨機數 
                    unsigned int randomNumber =arc4random() % ((unsigned int)RAND_MAX + 1); 
                    [arrayOfRandomNumbers addObject:[NSNumber numberWithUnsignedInt:randomNumber]]; 
                } 
                //將這個array寫入到磁盤上 
                [arrayOfRandomNumbers writeToFile:[self fileLocation] atomically:YES]; 
                 
            }); 
        } 
    //存放讀取文件內容的數組 
    __block NSMutableArray *randomNumbers = nil; 
    //從磁盤上讀取文件並升序排列 
    dispatch_sync(concurrentQueue, ^{ 
        //如果文件已經被創建,讀取他 
        if ([self hasFileAlreadyBeenCreated]){ 
            randomNumbers = [[NSMutableArray alloc] initWithContentsOfFile:[self fileLocation]]; 
            /* 排序 */ 
            [randomNumbers sortUsingComparator:^NSComparisonResult(id obj1, id obj2) 
             { 
                 NSNumber *number1 = (NSNumber *)obj1; 
                 NSNumber *number2 = (NSNumber *)obj2; 
                 return [number1 compare:number2]; 
             }]; 
        } 
    }); 
    dispatch_async(dispatch_get_main_queue(), ^{ 
        if ([randomNumbers count] > 0){ 
        /* 刷新主線程 */ 
            CGRect labelFrame = CGRectMake(0.0f, 0.0f, 300.0f, 200.0f); 
            self.myLabel = [[UILabel alloc] initWithFrame:labelFrame]; 
            self.myLabel.numberOfLines = 10;//分10行 
            NSString *str = [[NSString alloc] initWithFormat:@"RandomNumbers is %@",randomNumbers];//方法一 
            self.myLabel.text = str;//label的文字 
            self.myLabel.font = [UIFont boldSystemFontOfSize:14.0f];//字體樣式 
            self.myLabel.center = self.view.center;//UILabel控件居中 
            [self.view addSubview:self.myLabel]; 
        } 
    }); 
    }); 

 
//獲得文件路徑 
-(NSString *)fileLocation{ 
    /*  
     創建一個列表的目錄搜索路徑。 
     NSDocumentDirectory:文檔目錄。 
     NSUserDomainMask:用戶的主目錄的地方,存放用戶的個人項目。  
     */ 
    NSArray *folders = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES); 
    /* 如果沒有找到返回空 */ 
    if ([folders count] == 0) 
    {return nil; } 
    /* 獲得文件路徑的字符串形式 */ 
    NSString *documentsFolder = [folders objectAtIndex:0]; 
    //將文件名追加到foldser後面 
    return [documentsFolder stringByAppendingPathComponent:@"list.txt"]; 

 
//判斷文件是否被存在 
- (BOOL) hasFileAlreadyBeenCreated{ 
    BOOL result = NO; 
    //初始化NSFileManager文件管理對象 
    NSFileManager *fileManager = [[NSFileManager alloc] init]; 
    //判斷文件是否存在 
    if ([fileManager fileExistsAtPath:[self fileLocation]]) 
    { 
        result = YES; 
    } 
    return result; 

@synthesize myLabel;

- (void)viewDidLoad
{
    [super viewDidLoad];
 //聲明一個隊列
    dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    /*
     如果我們還沒有保存1000個隨機數在磁盤上,下面的隊列就用來生成這個文件並且用一個Array存放在磁盤上
     */
    dispatch_async(concurrentQueue, ^{
        NSUInteger numberOfValuesRequired = 10000;
        //判斷文件是否存在
        if ([self hasFileAlreadyBeenCreated]== NO){
            dispatch_sync(concurrentQueue, ^{
                //聲明一個可變數組用來存放數值
                NSMutableArray *arrayOfRandomNumbers =[[NSMutableArray alloc] initWithCapacity:numberOfValuesRequired];
                NSUInteger counter = 0;
                for (counter = 0;counter < numberOfValuesRequired;counter++){
                    //獲得隨機數
                    unsigned int randomNumber =arc4random() % ((unsigned int)RAND_MAX + 1);
                    [arrayOfRandomNumbers addObject:[NSNumber numberWithUnsignedInt:randomNumber]];
                }
                //將這個array寫入到磁盤上
                [arrayOfRandomNumbers writeToFile:[self fileLocation] atomically:YES];
               
            });
        }
    //存放讀取文件內容的數組
    __block NSMutableArray *randomNumbers = nil;
    //從磁盤上讀取文件並升序排列
    dispatch_sync(concurrentQueue, ^{
        //如果文件已經被創建,讀取他
        if ([self hasFileAlreadyBeenCreated]){
            randomNumbers = [[NSMutableArray alloc] initWithContentsOfFile:[self fileLocation]];
            /* 排序 */
            [randomNumbers sortUsingComparator:^NSComparisonResult(id obj1, id obj2)
             {
                 NSNumber *number1 = (NSNumber *)obj1;
                 NSNumber *number2 = (NSNumber *)obj2;
                 return [number1 compare:number2];
             }];
        }
    });
    dispatch_async(dispatch_get_main_queue(), ^{
        if ([randomNumbers count] > 0){
        /* 刷新主線程 */
            CGRect labelFrame = CGRectMake(0.0f, 0.0f, 300.0f, 200.0f);
            self.myLabel = [[UILabel alloc] initWithFrame:labelFrame];
            self.myLabel.numberOfLines = 10;//分10行
            NSString *str = [[NSString alloc] initWithFormat:@"RandomNumbers is %@",randomNumbers];//方法一
            self.myLabel.text = str;//label的文字
            self.myLabel.font = [UIFont boldSystemFontOfSize:14.0f];//字體樣式
            self.myLabel.center = self.view.center;//UILabel控件居中
            [self.view addSubview:self.myLabel];
        }
    });
    });
}

//獲得文件路徑
-(NSString *)fileLocation{
    /*
     創建一個列表的目錄搜索路徑。
     NSDocumentDirectory:文檔目錄。
     NSUserDomainMask:用戶的主目錄的地方,存放用戶的個人項目。
     */
    NSArray *folders = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
    /* 如果沒有找到返回空 */
    if ([folders count] == 0)
    {return nil; }
    /* 獲得文件路徑的字符串形式 */
    NSString *documentsFolder = [folders objectAtIndex:0];
    //將文件名追加到foldser後面
    return [documentsFolder stringByAppendingPathComponent:@"list.txt"];
}

//判斷文件是否被存在
- (BOOL) hasFileAlreadyBeenCreated{
    BOOL result = NO;
    //初始化NSFileManager文件管理對象
    NSFileManager *fileManager = [[NSFileManager alloc] init];
    //判斷文件是否存在
    if ([fileManager fileExistsAtPath:[self fileLocation]])
    {
        result = YES;
    }
    return result;
}
運行結果

 \
 


 

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved