你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> IOS開發(102)之GCD與block結合應用

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

編輯:IOS開發綜合

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

 


運行結果:

 \
 


點擊按鈕\
 


最後

 \
 


  

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