主要有四种
准备工作
#import "ViewController.h"
#import "MyOperation.h"
@interface ViewController ()
- (IBAction)buttonAction:(id)sender;
@property(nonatomic,retain)UIImageView *imageView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIButton *button=[UIButton buttonWithType:UIButtonTypeSystem];
button.frame=CGRectMake(150, 300, 100, 50);
button.backgroundColor=[UIColor cyanColor];
[self.view addSubview:button];
[button addTarget:self action:@selector(gcdAction:) forControlEvents:UIControlEventTouchUpInside];
[button setTitle:@"测试" forState:UIControlStateNormal];
self.imageView=[[UIImageView alloc] initWithFrame:CGRectMake(100, 400, 150, 150)];
self.imageView.backgroundColor=[UIColor orangeColor];
[self.view addSubview:self.imageView];
}
-(void)click:(UIButton *)button{
//可以让线程进行休眠
// [NSThread sleepForTimeInterval:3];
int count = 0;
for (NSInteger i = 0; i<1000000000; i++) {
NSLog(@"%ld",i);
}
NSLog(@"%d",count);
}
- (IBAction)buttonAction:(id)sender {
//模仿了主线程被卡死的效果,其他的操作什么都不能做了
int count = 0;
for (NSInteger i = 0; i<1000000000; i++) {
NSLog(@"%ld",i);
}
NSLog(@"%d",count);
}
//iOS实现多线程的四种方式
//1.NSObject自带多线程处理
-(void)NSObjectThread:(UIButton *)button{
[self performSelectorInBackground:@selector(click:) withObject:button];
//优点:这种开辟子线程的方式特别简单,可以开辟一个临时的线程
//缺点:因为开启过程过于简单,很多内容无法设置,不能注意到线程安全问题
}
//2.NSThread
-(void)NSThresdAction:(UIButton *)button{
//NSThread这个类本身就是线程类,创建一个NSThread对象相当于创建了一个子线程
NSThread *thread=[[NSThread alloc] initWithTarget:self selector:@selector(click:) object:nil];
//给线程对象起一个名
thread.name=@"尹德建";
//让线程对象开始工作
[thread start];
//优点:创建比之前要复杂一点,可以起名,可以让线程里的东西延迟进行等
//缺点:还是没有注意到线程安全等问题,用起来也较为麻烦
}
//3.NSOperation
-(void)NSOperationAction:(UIButton *)button{
//Operation 任务
//它本身是一个抽象类,带表了一个任务,如果想使用需要把要执行的动作放到这个类子类去执行
MyOperation *operation=[[MyOperation alloc] init];
[operation start];
//如果直接拿这个对象来使用,他的使用效果和主线程是一样的,如果想要他实现多线程,需要和NSOperationQueue配合使用
}
-(void)operationQueue:(UIButton *)button{
//使用操作队列来解决多线程问题
//队列:队列里有一个线程池,可以把一些闲置的线程进行重新利用,提高线程利用率
NSOperationQueue *queue=[[NSOperationQueue alloc] init];
//设置最大并发数
[queue setMaxConcurrentOperationCount:3];
//创建任务
MyOperation *operation1=[[MyOperation alloc] init];
MyOperation *operation2=[[MyOperation alloc] init];
MyOperation *operation3=[[MyOperation alloc] init];
MyOperation *operation4=[[MyOperation alloc] init];
MyOperation *operation5=[[MyOperation alloc] init];
//把任务添加到队列里
[queue addOperation:operation1];
[queue addOperation:operation2];
[queue addOperation:operation3];
[queue addOperation:operation4];
[queue addOperation:operation5];
//优点:能对线程资源进行重复利用,而且只要把任务方法放到队列里,就能对线程安全问题进行处理,使用起来相比较简单
//缺点:效率较低
}
方法3中使用的MyOperation.m
#import "MyOperation.h"
@implementation MyOperation
-(void)main{
int count = 0;
for (NSInteger i = 0; i<1000000000; i++) {
// NSLog(@"%ld",i);
}
NSLog(@"%d",count);
}
@end
//4.GCD (用的比较多)
-(void)gcdAction:(UIButton *)button{
//GCD:苹果提供的一种多线程问题的解决方案,整体来说非常高效易用,是目前多线程方案里最好的一种
//GCD的使用也和queue类型,都是使用队列方式去完成操作
//缺点就是代码看起来比较难理解,C语言的东西比较多
//1.自定义一个队列
//参数1:对列名
//参数2:设置队列执行方式,是串行还是并行
//DISPATCH_QUEUE_CONCURRENT 并行
//DISPATCH_QUEUE_SERIAL 串行
// dispatch_queue_t myQueue=dispatch_queue_create("heAn", DISPATCH_QUEUE_CONCURRENT);
// //通过队列执行任务
// //参数1:指定在哪个队列里执行
// //参数2:要把执行功能写在block里
// dispatch_async(myQueue, ^{
// int count = 0;
// for (NSInteger i = 0; i<1000000000; i++) {
// NSLog(@"%ld",i);
// }
// NSLog(@"%d",count);
//
// });
//图片的异步加载
//先通过多线程的方式先获取图片对应数据,然后找到主队列,刷新视图
//创建一个自定义队列
dispatch_queue_t queue=dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT);
//找到当前工程里的主队列
dispatch_queue_t mainQueue=dispatch_get_main_queue();
dispatch_async(queue, ^{
NSString *strURL=@"http://pic.baike.soso.com/p/20140404/20140404162443-1075855132.jpg";
NSURL *url=[NSURL URLWithString:strURL];
NSData *data=[NSData dataWithContentsOfURL:url];
UIImage *image=[UIImage imageWithData:data];
//找到主队列,然后对控件进行视图内容刷新
dispatch_async(mainQueue, ^{
self.imageView.image=image;
});
});
}