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
運行結果:
點擊按鈕
最後