多线程有4种
NSObject---NSObject自带的,但是他不能对数据进行保护
NSThread ---过于复杂,使用起来不够方便
NSOperationQueue ---操作队列,管理线程,内部有一个线程池,负责对现有的线程进行管理/重用
GDC(grand central dispatch); ----基于C的多线程解决方案
队列有两种(串行/并行)
MainViewController.m
#import "MainViewController.h" #import "MyOperation.h" @interface MainViewController () @property (nonatomic , retain)UIImageView *p_w_picpathView; @end @implementation MainViewController - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { // Custom initialization } return self; } - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(110, 100, 100, 30)]; [button setTitle:@"按钮" forState:UIControlStateNormal]; button.backgroundColor = [UIColor orangeColor]; button.layer.cornerRadius = 5; [self.view addSubview:button]; [button addTarget:self action:@selector(GCDAction:) forControlEvents:UIControlEventTouchUpInside]; [button release]; self.p_w_picpathView = [[UIImageView alloc] initWithFrame:CGRectMake(40, 150, 240, 300)]; self.p_w_picpathView.backgroundColor = [UIColor cyanColor]; [self.view addSubview:self.p_w_picpathView]; [_p_w_picpathView release]; } - (void)buttonClick:(UIButton *)button { NSLog(@"判断当前线程是不是主线程%d",[NSThread isMainThread]); //让当前的线程休眠3秒 [NSThread sleepForTimeInterval:3]; NSLog(@"休眠结束"); NSLog(@"当前线程: %@",[NSThread currentThread]) ; int a = 0; for (int i = 0 ; i < 600000000; i++) { a++; } NSLog(@"%d",a); } - (void)NSObjectAction:(UIButton *)button { //1.多线程的实现方式:NSObject自带的 //绑定一个方法,然后给他一个参数 优点:简介快速,缺点:不能对数据进行保护 [self performSelectorInBackground:@selector(buttonClick:) withObject:button]; } - (void)threadAciton:(UIButton *)button { //2.NStrread类 //这个类ude一个对象,就代表一个线程 优点:可以控制线程的所有方面 缺点:太复杂,使用起来不方便 NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(buttonClick:) object:button]; thread.name = @"刘亚芳"; //开始执行子线程 [thread start]; [thread release]; } - (void)operationAction:(UIButton *)button { //NSOperation类 //本身不能够实现多线程操作,代表一个任务(进程),安排在某个线程里面 MyOperation *opreation = [[MyOperation alloc] init]; //开始执行任务,执行的任务会在当前执行 [opreation start]; [opreation release]; // NSInvocationOperation *op1 = [NSInvocationOperation alloc] initWithTarget:<#(id)#> selector:<#(SEL)#> object:<#(id)#> // NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:<#^(void)block#>] } - (void)poerationQueueAction:(UIButton *)button { //NSOperationQueue 操作队列(管理线程,线程池) 队列有两类:(并行/串行) //内部有一个线程池,负责对现有的线程进行管理/重用 //创建一个新的队列 //主队列是一个串行队列 NSOperationQueue *queue = [[NSOperationQueue alloc] init]; //设置一个最大并发数(如果最大并发数为1,那么就为串行,否则为并行) [queue setMaxConcurrentOperationCount:1]; //向队列中添加任务 MyOperation *op1 = [[MyOperation alloc] init]; MyOperation *op2 = [[MyOperation alloc] init]; MyOperation *op3 = [[MyOperation alloc] init]; MyOperation *op4 = [[MyOperation alloc] init]; [queue addOperation:op1]; [queue addOperation:op2]; [queue addOperation:op3]; [queue addOperation:op4]; [op1 release]; [op2 release]; [op3 release]; [op4 release]; } - (void)GCDAction:(UIButton *)button { //GCD: grand central dispatch 基于C的多线程解决方案 //1.创建一个调度队列 //参数1: 队列名字 参数2:队列的类型(串行/并行) //DISPATCH_QUEUE_CONCURRENT---并行队列 //DISPATCH_QUEUE_SERIAL ---串行队列 dispatch_queue_t myQueue = dispatch_queue_create("liuyafang", DISPATCH_QUEUE_SERIAL); //2.使用的队列 //参数1:要在哪个队列执行 参数2:要执行的内容 dispatch_async(myQueue, ^{ //任务1 [self buttonClick:button]; }); dispatch_async(myQueue, ^{ //任务2 NSLog(@"==========="); }); //使用系统的队列 //系统提供了5个队列,1个串行队列(主队列),4个并行队列(全局队列) //获取系统的主队列 dispatch_queue_t mainQueue = dispatch_get_main_queue(); dispatch_async(mainQueue, ^{ //执行在主队列中要做的任务 //全部的UI任务(reloadDate ,给试图赋值) }); //获取全局队列 //参数1:获取哪一个全局队列 参数2:给未来使用的(必须填写0) dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //GCD的常见用法 //在全局队列中请求数据 dispatch_async(globalQueue, ^{ NSString *str = @"http://c.hiphotos.baidu.com/p_w_picpath/pic/item/d50735fae6cd7b8904ac489d0c2442a7d8330eef.jpg"; NSURL *url = [NSURL URLWithString:str]; //请求网络地址数据的同步方法 //因为这个方法在子线程(全局队列)中执行,所以不需要考虑死线程的问题 NSData *data = [NSData dataWithContentsOfURL:url]; UIImage *p_w_picpath = [UIImage p_w_picpathWithData:data]; //所有刷新UI的操作都必须回到主队列进行(跳回到子线程) dispatch_async(mainQueue, ^{ self.p_w_picpathView.p_w_picpath = p_w_picpath; }); }); dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(4 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ NSLog(@"乔老爷不该死啊!!!"); }); //一段代码值执行一次,(单列的创建) static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ NSLog(@"只执行一次"); }); } - (void)dealloc { [_p_w_picpathView release]; [super dealloc]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } /* #pragma mark - Navigation // In a storyboard-based application, you will often want to do a little preparation before navigation - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { // Get the new view controller using [segue destinationViewController]. // Pass the selected object to the new view controller. } */ @end
MyOperation.h
看继承关系---这个是继承与NSOperation
#import <Foundation/Foundation.h> @interface MyOperation : NSOperation @end
MyOperation.m
#import "MyOperation.h" @implementation MyOperation - (void)main { //自己定义的Operation的类,需要在mian方法中写要执行的任务内容 NSLog(@"当前线程:%@",[NSThread currentThread]); NSLog(@"是不是主线程尼:%d",[NSThread isMainThread]); int a = 0; for (int i = 0 ; i < 600000000; i++) { a++; } NSLog(@"%d",a); } @end