1 Preface
In the first two chapters, we introduced GCD and Block. This time, we will combine the two to see how much effect they will achieve after their combination. Let's wait and see!
2. Details
Do you still remember the previous SlowWorker project? Find him. Now let's modify it. In this way, we can shorten the processing time of our project, so that we don't need to run the two methods at the same time to improve the efficiency.
We added a progress bar UIActivityIndicatorView to improve the user experience:
Set 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 {
// Sleep the thread for 1 second
[NSThread sleepForTimeInterval: 1];
Return @ "Hi there ";
}
-(NSString *) processData :( NSString *) data {
[NSThread sleepForTimeInterval: 2];
// Uppercase Conversion
Return [data uppercaseString];
}
-(NSString *) caculateFirstResult :( NSString *) data {
[NSThread sleepForTimeInterval: 3];
// Obtain the length
Return [NSString stringWithFormat: @ "Number of chars: % d", [data length];
}
-(NSString *) caculateSenondResult :( NSString *) data {
[NSThread sleepForTimeInterval: 4];
// Replace "E" with "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];
// Obtain the current time
NSDate * startTime = [NSDate date];
/**
* Dispatch_async:
* We wrap the code in a program block and pass it to a GCD function named dispatch_async.
* First parameter: a gcd queue
* Second parameter: it is the program block allocated to this queue.
* Dispatch_get_global_queue:
* Capture a global queue that already exists and is always available.
* First parameter: different priorities are set, such as DISPATCH_QUEUE_PRIORITY_HIGH or priority. Passing 0 is equivalent to passing in DISPATCH_QUEUE_PRIORITY_DEFAULT. Actually, a different global queue is obtained. The system will assign different priorities to this queue.
* The value of the second parameter is retained for future use. Always use 0.
*/
Dispatch_async (dispatch_get_global_queue (0, 0), ^ {
NSString * fetchedData = [self fechSomethingFromServer];
NSString * processedData = [self processData: fetchedData];
// Because these two variables are dynamic, use _ block to modify them.
_ Block NSString * firstResult;
_ Block NSString * secondResult;
/**
* Assign a group. In the context of a group, all program blocks asynchronously distributed using the dispatch_group_async () function are set to loose to execute as quickly as possible. If possible, distribute them to multiple threads for simultaneous execution.
*/
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];
});
/**
* You can also use dispatch_group_notify () to specify an additional program block, which will be executed when all program blocks in the group are completed.
*/
Dispatch_group_notify (group, dispatch_get_global_queue (0, 0), ^ {
NSString * resultsSummary = [NSString stringWithFormat: @ "First: [% @] \ nSecond: [% @]", firstResult, secondResult];
/**
* Any GUI objects connected from the background are impossible. Therefore, you need to call another dispatch function to return the work to the main thread! Call the queue returned by the pass-In dispatch_get_main_queue () function again. This function always provides a special queue for the main thread and is ready to run the module that needs to use the main thread.
*/
Dispatch_async (dispatch_get_main_queue (), ^ {
StartButton. enabled = YES;
StartButton. alpha = 1;
[Spinner stopAnimating];
// Assign a value to the text attribute of resultsTextView
ResultsTextView. text = resultsSummary;
});
});
NSDate * endTime = [NSDate date];
// Obtain the time difference in seconds.
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 {
// Sleep the thread for 1 second
[NSThread sleepForTimeInterval: 1];
Return @ "Hi there ";
}
-(NSString *) processData :( NSString *) data {
[NSThread sleepForTimeInterval: 2];
// Uppercase Conversion
Return [data uppercaseString];
}
-(NSString *) caculateFirstResult :( NSString *) data {
[NSThread sleepForTimeInterval: 3];
// Obtain the length
Return [NSString stringWithFormat: @ "Number of chars: % d", [data length];
}
-(NSString *) caculateSenondResult :( NSString *) data {
[NSThread sleepForTimeInterval: 4];
// Replace "E" with "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];
// Obtain the current time
NSDate * startTime = [NSDate date];
/**
* Dispatch_async:
* We wrap the code in a program block and pass it to a GCD function named dispatch_async.
* First parameter: a gcd queue
* Second parameter: it is the program block allocated to this queue.
* Dispatch_get_global_queue:
* Capture a global queue that already exists and is always available.
* First parameter: different priorities are set, such as DISPATCH_QUEUE_PRIORITY_HIGH or priority. Passing 0 is equivalent to passing in DISPATCH_QUEUE_PRIORITY_DEFAULT. Actually, a different global queue is obtained. The system will assign different priorities to this queue.
* The value of the second parameter is retained for future use. Always use 0.
*/
Dispatch_async (dispatch_get_global_queue (0, 0), ^ {
NSString * fetchedData = [self fechSomethingFromServer];
NSString * processedData = [self processData: fetchedData];
// Because these two variables are dynamic, use _ block to modify them.
_ Block NSString * firstResult;
_ Block NSString * secondResult;
/**
* Assign a group. In the context of a group, all program blocks asynchronously distributed using the dispatch_group_async () function are set to loose to execute as quickly as possible. If possible, distribute them to multiple threads for simultaneous execution.
*/
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];
});
/**
* You can also use dispatch_group_notify () to specify an additional program block, which will be executed when all program blocks in the group are completed.
*/
Dispatch_group_notify (group, dispatch_get_global_queue (0, 0), ^ {
NSString * resultsSummary = [NSString stringWithFormat: @ "First: [% @] \ nSecond: [% @]", firstResult, secondResult];
/**
* Any GUI objects connected from the background are impossible. Therefore, you need to call another dispatch function to return the work to the main thread! Call the queue returned by the pass-In dispatch_get_main_queue () function again. This function always provides a special queue for the main thread and is ready to run the module that needs to use the main thread.
*/
Dispatch_async (dispatch_get_main_queue (), ^ {
StartButton. enabled = YES;
StartButton. alpha = 1;
[Spinner stopAnimating];
// Assign a value to the text attribute of resultsTextView
ResultsTextView. text = resultsSummary;
});
});
NSDate * endTime = [NSDate date];
// Obtain the time difference in seconds.
NSLog (@ "Completed in % f seconds", [endTime timeIntervalSinceDate: startTime]);
});
}
@ End
Running result:
Click
Last