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