IOS開發(102)之GCD與block結合應用

來源:互聯網
上載者:User

1 前言
前兩章我們介紹了GCD和Block,這次我們將二者結合到一起,看看他們之間合體之後到底會發揮多大的效果0 0,讓我們拭目以待!

2 詳述
還記得之前的那個SlowWorker項目嗎?翻出來找到他,現在我們開始修改它。從而讓我們的項目已耗用時間縮短處理時間,使之前無需同時進行的兩個方法,並發進行,提高效率,廢話少說,上代碼。

在原來的基礎上我們添加了一個進度條UIActivityIndicatorView,用於提高使用者體驗:

 



設定Hides When Stopped:

 
 

 

ZYViewController.m:


[plain]

//  ZYViewController.m 
//  SlowWorker 
// 
//  Created by zhangyuc on 13-6-7. 
//  Copyright (c) 2013年 zhangyuc. All rights reserved. 
// 
 
#import "ZYViewController.h" 
 
@interface ZYViewController () 
 
@end 
 
@implementation ZYViewController 
 
@synthesize startButton,resultsTextView; 
@synthesize spinner; 
 
-(NSString *)fechSomethingFromServer{ 
    //讓線程休眠1秒 
    [NSThread sleepForTimeInterval:1]; 
    return @"Hi there"; 

 
-(NSString *)processData:(NSString *)data{ 
    [NSThread sleepForTimeInterval:2]; 
    //大寫轉換 
    return [data uppercaseString]; 

 
-(NSString *)caculateFirstResult:(NSString *)data{ 
    [NSThread sleepForTimeInterval:3]; 
    //獲得長度 
    return [NSString stringWithFormat:@"Number of chars:%d",[data length]]; 

 
-(NSString *)caculateSenondResult:(NSString *)data{ 
    [NSThread sleepForTimeInterval:4]; 
    //將“E”替換成“e” 
    return [data stringByReplacingOccurrencesOfString:@"E" withString:@"e"]; 

 
- (void)viewDidLoad 

    [super viewDidLoad]; 
    // Do any additional setup after loading the view, typically from a nib. 

 
- (void)didReceiveMemoryWarning 

    [super didReceiveMemoryWarning]; 
    // Dispose of any resources that can be recreated. 

 
- (void)dealloc { 
    [startButton release]; 
    [resultsTextView release]; 
    [spinner release]; 
    [super dealloc]; 

- (IBAction)doWorking:(id)sender { 
     
    startButton.enabled = NO; 
    startButton.alpha = 0.5; 
    [spinner startAnimating]; 
     
    //獲得目前時間 
    NSDate* startTime = [NSDate date]; 
    /** 
     *dispatch_async: 
     *我們將程式碼封裝裝在一個程式塊中並將它傳遞給一個名為dispatch_async的GCD函數。 
     *第一個參數:一個GCD隊列 
     *第二個參數:為分配給這個隊列的程式塊 
     *dispatch_get_global_queue: 
     *抓取一個已經存在並始終可用的全域隊列。 
     *第一個參數:制定了不同的優先順序,比如DISPATCH_QUEUE_PRIORITY_HIGH或者DISPATCH_QUEUE_PRIORITY_LOW,傳0相當於傳入DISPATCH_QUEUE_PRIORITY_DEFAULT,實際擷取一個不同的全域隊列,系統將對該隊列分配不同的優先順序。 
     *第二個參數 這個值保留以供將來使用。應該總是使用0。 
     */ 
    dispatch_async(dispatch_get_global_queue(0, 0), ^{ 
        NSString* fetchedData = [self fechSomethingFromServer]; 
        NSString* processedData = [self processData:fetchedData]; 
        //由於這兩個變數是動態所以要用__block修飾 
        __block NSString* firstResult; 
        __block NSString* secondResult; 
        /** 
         *指派組。將在一個組的上下文中通過dispatch_group_async()函數非同步指派的所有程式塊設定為鬆散的,以儘可能快地執行,如果可能,將他們分發給多個線程同時執行。 
         */ 
        dispatch_group_t group = dispatch_group_create(); 
        dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{ 
            firstResult = [self caculateFirstResult:processedData]; 
        }); 
        dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{ 
            secondResult = [self caculateSenondResult:processedData]; 
        }); 
        /** 
         *也可以使用dispatch_group_notify()指定一個額外的程式塊,該程式塊將在組中的所有程式塊運行完成時執行。 
         */ 
        dispatch_group_notify(group, dispatch_get_global_queue(0, 0), ^{ 
             NSString* resultsSummary = [NSString stringWithFormat:@"First:[%@]\nSecond:[%@]",firstResult,secondResult]; 
            /** 
             *從後台聯絡到的任何GUI對象是不可能的,所以需要調用另一個指派函數,將工作回到主線程!再次調用傳入dispatch_get_main_queue()函數返回的隊列,該函數總是提供用於主線程上的特殊隊列,並準備執行需要使用主線程的模組。 
             */ 
            dispatch_async(dispatch_get_main_queue(), ^{ 
                startButton.enabled = YES; 
                startButton.alpha = 1; 
                [spinner stopAnimating]; 
                //為resultsTextView的text屬性賦值 
                resultsTextView.text = resultsSummary; 
            }); 
        }); 
        NSDate* endTime = [NSDate date]; 
        //獲得時間差單位 s 
        NSLog(@"Completed in %f seconds",[endTime timeIntervalSinceDate:startTime]); 
    }); 

@end 

//
//  ZYViewController.m
//  SlowWorker
//
//  Created by zhangyuc on 13-6-7.
//  Copyright (c) 2013年 zhangyuc. All rights reserved.
//

#import "ZYViewController.h"

@interface ZYViewController ()

@end

@implementation ZYViewController

@synthesize startButton,resultsTextView;
@synthesize spinner;

-(NSString *)fechSomethingFromServer{
    //讓線程休眠1秒
    [NSThread sleepForTimeInterval:1];
    return @"Hi there";
}

-(NSString *)processData:(NSString *)data{
    [NSThread sleepForTimeInterval:2];
    //大寫轉換
    return [data uppercaseString];
}

-(NSString *)caculateFirstResult:(NSString *)data{
    [NSThread sleepForTimeInterval:3];
    //獲得長度
    return [NSString stringWithFormat:@"Number of chars:%d",[data length]];
}

-(NSString *)caculateSenondResult:(NSString *)data{
    [NSThread sleepForTimeInterval:4];
    //將“E”替換成“e”
    return [data stringByReplacingOccurrencesOfString:@"E" withString:@"e"];
}

- (void)viewDidLoad
{
    [super viewDidLoad];
 // Do any additional setup after loading the view, typically from a nib.
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)dealloc {
    [startButton release];
    [resultsTextView release];
    [spinner release];
    [super dealloc];
}
- (IBAction)doWorking:(id)sender {
   
    startButton.enabled = NO;
    startButton.alpha = 0.5;
    [spinner startAnimating];
   
    //獲得目前時間
    NSDate* startTime = [NSDate date];
    /**
     *dispatch_async:
     *我們將程式碼封裝裝在一個程式塊中並將它傳遞給一個名為dispatch_async的GCD函數。
     *第一個參數:一個GCD隊列
     *第二個參數:為分配給這個隊列的程式塊
     *dispatch_get_global_queue:
     *抓取一個已經存在並始終可用的全域隊列。
     *第一個參數:制定了不同的優先順序,比如DISPATCH_QUEUE_PRIORITY_HIGH或者DISPATCH_QUEUE_PRIORITY_LOW,傳0相當於傳入DISPATCH_QUEUE_PRIORITY_DEFAULT,實際擷取一個不同的全域隊列,系統將對該隊列分配不同的優先順序。
     *第二個參數 這個值保留以供將來使用。應該總是使用0。
     */
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        NSString* fetchedData = [self fechSomethingFromServer];
        NSString* processedData = [self processData:fetchedData];
        //由於這兩個變數是動態所以要用__block修飾
        __block NSString* firstResult;
        __block NSString* secondResult;
        /**
         *指派組。將在一個組的上下文中通過dispatch_group_async()函數非同步指派的所有程式塊設定為鬆散的,以儘可能快地執行,如果可能,將他們分發給多個線程同時執行。
         */
        dispatch_group_t group = dispatch_group_create();
        dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
            firstResult = [self caculateFirstResult:processedData];
        });
        dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
            secondResult = [self caculateSenondResult:processedData];
        });
        /**
         *也可以使用dispatch_group_notify()指定一個額外的程式塊,該程式塊將在組中的所有程式塊運行完成時執行。
         */
        dispatch_group_notify(group, dispatch_get_global_queue(0, 0), ^{
             NSString* resultsSummary = [NSString stringWithFormat:@"First:[%@]\nSecond:[%@]",firstResult,secondResult];
            /**
             *從後台聯絡到的任何GUI對象是不可能的,所以需要調用另一個指派函數,將工作回到主線程!再次調用傳入dispatch_get_main_queue()函數返回的隊列,該函數總是提供用於主線程上的特殊隊列,並準備執行需要使用主線程的模組。
             */
            dispatch_async(dispatch_get_main_queue(), ^{
                startButton.enabled = YES;
                startButton.alpha = 1;
                [spinner stopAnimating];
                //為resultsTextView的text屬性賦值
                resultsTextView.text = resultsSummary;
            });
        });
        NSDate* endTime = [NSDate date];
        //獲得時間差單位 s
        NSLog(@"Completed in %f seconds",[endTime timeIntervalSinceDate:startTime]);
    });
}
@end

 


運行結果:

 
 


點擊按鈕
 


最後

 
 


  

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.