大家都知道,多线程是当今编程的主流,如何运行速度更快效率更好,多线程的处理是大大的功臣.
可是多线程的处理也是一个很棘手而且很严肃的话题,多线程的不确定性也给程序员带来了很大的苦难.
现在就apple的一些多线程处理的优点进行总结:
1.首先,看看GCD的多线程处理吧,主要是使用block 和 GCD来处理多线程.
#import <UIKit/UIKit.h>
@interface BIDViewController : UIViewController
@property (strong, nonatomic) IBOutlet UIButton *startButton;
@property (strong, nonatomic) IBOutlet UITextView *resultTextView;
@property (strong,nonatomic)IBOutlet UIActivityIndicatorView *spinner;
- (IBAction)dowork:(id)sender;
@end
一个button,一个textview显示result,还有一个UIActivityIndicatorView 进行运行状态下的等待操作.
2.在.m文件中首先使用了一个
1). button pressed 的非多线程的方式.代码如下:
- (IBAction)dowork:(id)sender {
NSDate *startTime = [NSDate date];
NSString *data = [self fetchSomethingFromServer];
NSString *processedData = [self processData:data];
NSString *firstResult = [self calculateFirstResult:processedData];
NSString *secondResult = [self calculateSecondResult:processedData];
NSString *resultSummary = [NSString stringWithFormat:@"stratTime:%@,proessedData:%@,firstResult:%@,secondResult:%@",startTime,processedData,firstResult,secondResult];
resultTextView.text = resultSummary;
NSDate *endTime = [NSDate date];
NSLog(@"completed time :%f seconds.",[endTime timeIntervalSinceDate:startTime]);
}
上述代码主要是写了一系列关于字符串的处理,模拟了server的获取数据并处理.特别需要看到两行代码:
NSString *firstResult = [self calculateFirstResult:processedData];
NSString *secondResult = [self calculateSecondResult:processedData];
是不是能觉得这两行可以并发处理呢?
2)使用block进行处理,并没有实现多线程.
//版本2 : 我们设计了一个block进行处理,但是并没有节约时间.知识把一些操作放在了block中,并添加了UIActivityIndicatorView 控件的读取支持.而且通过运行发现,当进入blcok之后,dowrok将终止程序并释放.
- (IBAction)dowork:(id)sender {
startButton.enabled = NO;
startButton.alpha =0.5;
spinner.hidden = NO;
[spinner startAnimating];
NSDate *startTime = [NSDate date];
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSString *data = [self fetchSomethingFromServer];
NSString *processedData = [self processData:data];
NSString *firstResult = [self calculateFirstResult:processedData];
NSString *secondResult = [self calculateSecondResult:processedData];
NSString *resultSummary = [NSString stringWithFormat:@"stratTime:%@,proessedData:%@,firstResult:%@,secondResult:%@",startTime,processedData,firstResult,secondResult];
dispatch_sync(dispatch_get_main_queue(), ^{
startButton.enabled = YES;
[spinner stopAnimating ];
spinner.hidden = YES;
resultTextView.text = resultSummary;
});
//定义了一个从block内部到外部的一个代码,使能够传值到外边来
});
//如果endtime放在block内部的话,而开始的时间在 block外部,当进block的时候 dowork:其实已经结束了.starttime就释放了.
//
NSDate *endTime = [NSDate date];
NSLog(@"completed time :%f seconds.",[endTime timeIntervalSinceDate:startTime]);
其实上述代码得到时间很短,因为我们的app进入block之后便结束了dowork,所以会直接进行后续blcok以外的代码.
3.使用block,实现多线程并发的代码:
- (IBAction)dowork:(id)sender {
startButton.enabled = NO;
startButton.alpha =0.5;
spinner.hidden = NO;
[spinner startAnimating];
NSDate *startTime = [NSDate date];
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSString *data = [self fetchSomethingFromServer];
NSString *processedData = [self processData:data];
// NSString *firstResult = [self calculateFirstResult:processedData];
// NSString *secondResult = [self calculateSecondResult:processedData];
__block NSString *firstResult;//希望我们的值可以传到block之外,所以定义为__block类型.
__block NSString *secondResult;
dispatch_group_t group = dispatch_group_create();//创建一个组,用于放线程.
dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
firstResult = [self calculateFirstResult:processedData];
});
dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
secondResult = [self calculateSecondResult:processedData];
});
dispatch_group_notify(group, dispatch_get_global_queue(0, 0), ^{
//notify 只有当所有其他进程执行完毕,才会执行此block.
NSString *resultSummary = [NSString stringWithFormat:@"stratTime:%@,proessedData:%@,firstResult:%@,secondResult:%@",startTime,processedData,firstResult,secondResult];
dispatch_sync(dispatch_get_main_queue(), ^{
startButton.enabled = YES;
[spinner stopAnimating ];
spinner.hidden = YES;
resultTextView.text = resultSummary;
});
NSDate *endTime = [NSDate date];
NSLog(@"completed time :%f seconds.",[endTime timeIntervalSinceDate:startTime]);
});
//定义了一个从block内部到外部的一个代码,使能够传值到外边来
});
//如果endtime放在block内部的话,而开始的时间在 block外部,当进block的时候 dowork:其实已经结束了.starttime就释放了.
//
1,2代码的执行时间为10s左右,而第三个代码的执行时间为7s左右.
现在看看,多线程的处理是不是很简单呢 ?