多线程
先在storyboard上绘制两颗按钮,并且绑定事件。
先看下面一段代码:
- (IBAction)blueButtonClicked:(UIButton *)sender {
NSLog(@"蓝色按钮任务开始执行");
// 模拟任务需要执行5s
sleep(5);
NSLog(@"蓝色按钮任务已经完成");
}
- (IBAction)yellowButtonClicked:(UIButton *)sender {
NSLog(@"黄色按钮任务完成");
}
点击蓝色按钮之后就会卡在那里了,如果此时点击黄色按钮,不能看到NSLog打印的语句,但事实上任务已经执行了,必须等到蓝色按钮执行的事件执行完之后控制台才能打印出来。
多线程
- (void) bar:(UIButton *)sender{
sender.enabled = YES;
[sender setTitle:@"蓝色" forState:UIControlStateNormal];
}
- (IBAction)yellowButtonClicked:(UIButton *)sender {
NSLog(@"黄色按钮任务完成");
}
- 第一种方式
- (IBAction)blueButtonClicked:(UIButton *)sender {
[sender setTitle:@"正在执行..." forState:UIControlStateNormal];
sender.enabled = NO;
// 提示:对于那些耗时间的任务基本上都应该放到其它的执行线程中
// 不要阻塞主线程的执行 否则界面会出现卡顿或假死现象
// 模拟任务需要执行5s
//sleep(5);
//NSLog(@"蓝色按钮任务已经完成");
[self performSelectorInBackground:@selector(foo:) withObject:sender];
}
- (void) foo:(UIButton *)sender{
sleep(5);
NSLog(@"蓝色按钮任务已经完成");
// 执行完之后要恢复按钮的状态
//sender.enabled = YES;
//[sender setTitle:@"蓝色" forState:0];
// 提示:刷新视图界面要回到主线程执行,如果直接在这里执行 可能会失效
[self performSelectorOnMainThread:@selector(bar:) withObject:sender waitUntilDone:YES];
}
- 第二种方式1
- (IBAction)blueButtonClicked:(UIButton *)sender {
[sender setTitle:@"正在执行..." forState:UIControlStateNormal];
sender.enabled = NO;
[NSThread detachNewThreadSelector:@selector(foo:) toTarget:self withObject:sender];
}
- (void) foo:(UIButton *)sender{
sleep(5);
NSLog(@"蓝色按钮任务已经完成");
[self performSelectorOnMainThread:@selector(bar:) withObject:sender waitUntilDone:YES];
}
- 第二种方式2
- (IBAction)blueButtonClicked:(UIButton *)sender {
[sender setTitle:@"正在执行..." forState:UIControlStateNormal];
sender.enabled = NO;
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(foo:) object:sender];
[thread start];
//[thread cancel];// 如果加上这句任务取消
// 如果线程已经开始执行则无法取消
// 下面的方法任务不能取消
//[thread start];
//sleep(1);
//[thread cancel];
}
- (void) foo:(UIButton *)sender{
// 休眠和退出都是只有正在执行的线程可以调用的方法
// 因此在设计上这两个方法都是类方法而不是对象方法
//[NSThread exit];
sleep(5);
NSLog(@"蓝色按钮任务已经完成");
[self performSelectorOnMainThread:@selector(bar:) withObject:sender waitUntilDone:YES];
}
- 第三种方式
- (IBAction)blueButtonClicked:(UIButton *)sender {
[sender setTitle:@"正在执行..." forState:UIControlStateNormal];
sender.enabled = NO;
// 创建一个操作对象(将该操作放到一个队列中去执行)
NSOperation *op = [NSBlockOperation blockOperationWithBlock:^{
[self foo:sender];
}];
// 创建一个并发队列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
// 设置最大并发数
queue.maxConcurrentOperationCount = 5;
// 向队列中添加一个操作
[queue addOperation:op];
}
- (void) foo:(UIButton *)sender{
sleep(5);
NSLog(@"蓝色按钮任务已经完成");
// 创建一个操作对象
NSOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(bar:) object:sender];
// 向主线程操作队列中添加操作对象(操作放到主线程中执行)
[[NSOperationQueue mainQueue] addOperation:op];
}
- 第四种方法
- (IBAction)blueButtonClicked:(UIButton *)sender {
[sender setTitle:@"正在执行..." forState:UIControlStateNormal];
sender.enabled = NO;
// GCD - Grand Center Dispatch
dispatch_async(dispatch_get_global_queue(0, 0), ^{
sleep(5);
NSLog(@"蓝色按钮任务已经完成");
dispatch_async(dispatch_get_main_queue(), ^{
sender.enabled = YES;
[sender setTitle:@"蓝色" forState:UIControlStateNormal];
});
});
}