多线程

程序:就是代码⽣成的可执⾏的应⽤。    
进程:跑起来的程序。      
线程:程序中独⽴运⾏的代码段。(block就是)。      
⼀个进程是由多个线程(⼀个以上)组成的。进程申请资源和分配资源给线程⽤,线程⽤到资源。   
 
每个进程都包含⾄少⼀个线程,即主线程。主线程在程序跑动的时候被创建,⽤于执⾏main函数⾥的东西。 
 
主线程负责的是,所有代码的执⾏,包括UI更新,⽹络请求,本地存储等等。
主线程的代码都是顺序执⾏,不能并⾏执⾏。 
 
⽤户可以开辟许多新的线程,这些线程都是主线程的⼦线程。 
注意的是,主线程和⼦线程都是相互独⽴执⾏代码的,互不影响,并发执⾏。 
 
注意:UI更新,必须放在主线程中去更新。因为开辟的⼦线程,是不受控制的,什么时候执⾏完毕我们⽆法控制。再⼦线程更新UI出现的bug⽆法预料。
NSThread是相对于后⾯两个NSOperationQueue、GCD来说,是⼀个轻量级的多线程。
 
//
//  ViewController.m
//  多线程
//
//  Created by cqy on 16/2/16.
//  Copyright © 2016年 程清杨. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()
{
    NSThread *_thread;
    int i ;
}
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    NSThread *newThead = [NSThread currentThread];//获取当前线程
    NSThread *mainThead = [NSThread mainThread];//获取主线程
    [newThead setName:@"线程名"];
    if ([newThead isMainThread]) {
        NSLog(@"currentThread = %@",mainThead);
    }
   
   
    //第一种创建NSThread(第⼀种创建⽅式:需要⼿动启动[thread start];也要⼿动结束[thread cancel];⼦线程。)
   //第⼀个参数:随来执⾏
   // 第⼆个参数:去执⾏什么⽅法?这个⽅法⾥⼀般是⼦线程要完成的⼀些事:(⺴络请求,或者其他)。
   // 第三个参数:去执⾏的那个⽅法,顺便带⼀个参数过去。
   
   // NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(threadAction:) object:nil];
    //手动开启线程
    //[thread start];
    //结束线程
    //[thread cancel];
    // //第⼆种创建⽅式:不需要⼿动去开启⼦线程。参数意义与第⼀种⼀样。
   // [NSThread detachNewThreadSelector:@selector(threadAction:) toTarget:self withObject:@"qwe"];
    //隐式创建线程
    //[self performSelectorInBackground:@selector(threadAction:) withObject:self];
    // 在主线程上执行
    [self performSelectorOnMainThread:@selector(Open) withObject:self waitUntilDone:YES];
    // Do any additional setup after loading the view, typically from a nib.
}
-(void)Open{
    NSLog(@"open...");
    //新创建一个子线程
    [NSThread detachNewThreadSelector:@selector(threadAction:) toTarget:self withObject:@"qwe"];
   
   
}
-(void)threadAction:(NSThread *)sender{
     NSLog(@"threadAction...");
    NSTimer *timer=[NSTimer timerWithTimeInterval:0.5 target:self selector:@selector(timeSchedule) userInfo:nil repeats:YES];
   
    NSRunLoop *runLoop=[NSRunLoop currentRunLoop];
   
    [runLoop addTimer:timer forMode:NSDefaultRunLoopMode];
    while ([runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]);
  
}
-(void)timeSchedule{
     NSLog(@"timeSchedule...");
  
    NSLog(@"now is %d",i++);
    //在指定线程上执行操作
    _thread = [[NSThread alloc]initWithTarget:self selector:@selector(WillClose) object:nil];
    //暂停当前线程几秒
    [NSThread sleepForTimeInterval:3];
    [_thread start];
   }
-(void)WillClose{
  
        NSLog(@"will close...");
   
    [self performSelector:@selector(Close) onThread:_thread withObject:nil waitUntilDone:YES];
    }
-(void)Close{
    NSLog(@"close............");
    //停止当前线程
    [NSThread exit];

}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/*
注意:
再多线程⽅法中,需要添加⾃动释放池。
应⽤程序再启动时,系统⾃动为主线程创建了⾃动释放池。我们⼿动添加的⼦
线程,需要添加⾃动释放池。
 */
@end
 
NSOperation  
NSOperation  
mvc中属于M层,⽤来封装单个任务的相关代码的⼀个抽象类。这个抽象类不能直接使⽤,⽽是⽤它的⼦类来执⾏实际任务。    
NSOperation只是⼀个操作,本⾝并没有主线程、⼦线程之分,可以使⽤再任意线程中。通常与NSOperationQueue⼀起使⽤。
//
//  ViewController.m
//  多线程02-NSOperation
//
//  Created by cqy on 16/2/16.
//  Copyright © 2016年 程清杨. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    NSInvocationOperation *inOp = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(operationAction:) object:nil];
    [inOp start];
    //封装了要执⾏的代码块。要执⾏的代码都放在block⾥执⾏了。
    NSBlockOperation *blockOp = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"block操作0:%@",[NSThread currentThread]);
       
        }];
    //在NSBlockOperation对象中添加一个操作,如果NSBlockOperation对象包含了多个操作,有一个是在主线程中执行,其他均在子线程中
    [blockOp addExecutionBlock:^{
        NSLog(@"block操作1:%@",[NSThread currentThread]);
    }];
    [blockOp addExecutionBlock:^{
        NSLog(@"block操作2:%@",[NSThread currentThread]);
    }];
   
    [blockOp start];
  
    //注意:添加操作之前要放在start之前
    //创建队列:将操作放入队列中(主队列除外),默认在子线程中执行,且不需要手动start
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    NSInvocationOperation *Operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run2) object:nil];
    [queue addOperation:Operation];
    [queue addOperationWithBlock:^{
        NSLog(@"block操作队列3:%@",[NSThread currentThread]);
    }];
   
    // Do any additional setup after loading the view, typically from a nib.
}
-(void)run2{
    NSLog(@"队列执行操作4:%@",[NSThread currentThread]);
}
-(void)operationAction:(NSInvocationOperation *)sender{
    NSLog(@"operationAction....");
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
@end
 
GCD
 
GCD是苹果公司封装好的⼀个系统,⽤来应对多核处理系统。gcd⼤部分代码都是函数的多线程,性能⾼,功能强⼤。      
GCD以队列的⽅式进⾏⼯作,先进先出(o),GCD根据分发队列的的类型,创建适量线程,完成⼯作。     
cgd分为三种队列:     
主队列,全局队列,⾃定义队列。 
1、串⾏队列:前⼀个任务完成,才能执⾏下⼀个任务(包括主队列和⾃定义队列)   
2、并⾏队列:各个任务独⽴执⾏,互不⼲扰,也是先进先出(包括了全局队列和⾃定义队列)。 
 
//
//  ViewController.m
//  多线程03-GCD
//
//  Created by cqy on 16/2/16.
//  Copyright © 2016年 程清杨. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self oneMain];
    [self twoMain];
    [self threeMain];
    [self fourMain];
   
    // Do any additional setup after loading the view, typically from a nib.
}
-(void)oneMain{
    // 主队列(串)
    //dispatch_queue_t是⼀个类型,mainQueue是类型的实例名。
    dispatch_queue_t mainQueue = dispatch_get_main_queue();
    //dispatch_get_main_queue(),获取主队列
    // 添加任务(三种队列都⽤这个⽅法添加)
    dispatch_async(mainQueue, ^{
        //dispatch_async(mainQueue,^(block)),这个⽅法是吧任务添加到mainQueue主队列中。block块⾥是要执⾏的任务。
        NSLog(@"第1个任务,当前线程:%@",[NSThread currentThread]);
    });
    dispatch_async(mainQueue, ^{
        NSLog(@"第2个任务,当前线程:%@",[NSThread currentThread]);
    });
    dispatch_async(mainQueue, ^{
        NSLog(@"第3个任务,当前线程:%@",[NSThread currentThread]);
    });
    dispatch_async(mainQueue, ^{
        NSLog(@"第4个任务,当前线程:%@",[NSThread currentThread]);
    });
    dispatch_async(mainQueue, ^{
        NSLog(@"第5个任务,当前线程:%@",[NSThread currentThread]);
    });
    dispatch_async(mainQueue, ^{
         NSLog(@"第6个任务,当前线程:%@",[NSThread currentThread]);
    });
    //解释:1、dispatch_queue_create 是创建⾃定义队列的⽅式。第⼀个参数是队列标⽰符,第⼆个参数是告诉系统,这个队列是串⾏的。2、dispatch_async,添加任务到myQueue1这个⾃定义队列中。block块中是执⾏的任务。
}
-(void)twoMain{
    // ⾃定义队列(串)
    // 第⼆个参数,告诉是串⾏的。
    dispatch_queue_t myQueue = dispatch_queue_create("myQ1",   DISPATCH_QUEUE_SERIAL);
    dispatch_async(myQueue, ^{
        NSLog(@"第01个任务,当前线程:%@",[NSThread  currentThread]);
    });
    dispatch_async(myQueue, ^{
        NSLog(@"第02个任务,当前线程:%@",[NSThread currentThread]);
    });
    dispatch_async(myQueue, ^{
        NSLog(@"第03个任务,当前线程:%@",[NSThread currentThread]);
    });
    dispatch_async(myQueue, ^{
        NSLog(@"第04个任务,当前线程:%@",[NSThread currentThread]);
    });
   
}
-(void)threeMain{
    // 全局(并⾏)
    dispatch_queue_t globelQ =
    dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
                              0);
    dispatch_async(globelQ, ^{
        NSLog(@"第-1个任务,当前线程为:%@",[NSThread currentThread]);
    });
    dispatch_async(globelQ, ^{
        NSLog(@"第-2个任务,当前线程为:%@",[NSThread currentThread]);
    });
    dispatch_async(globelQ, ^{
        NSLog(@"第-3个任务,当前线程为:%@",[NSThread currentThread]);
    });
    dispatch_async(globelQ, ^{
        NSLog(@"第-5个任务,当前线程为:%@",[NSThread currentThread]);
    });
    dispatch_async(globelQ, ^{
        NSLog(@"第-6个任务,当前线程为:%@",[NSThread currentThread]);
    });
    // 解释dispatch_get_global_queue创建⼀个全局队列。DISPATCH_QUEUE_PRIORITY_DEFAULT:队列的优先级,default是系统默认。
   
   
   
}
-(void)fourMain{
    // ⾃定义(并⾏)
    dispatch_queue_t myQueue2 = dispatch_queue_create("Q2",          DISPATCH_QUEUE_CONCURRENT);
   
    dispatch_async(myQueue2, ^{
        NSLog(@"第1-个任务,当前线程为:%@",[NSThread currentThread]);
    });
    dispatch_async(myQueue2, ^{
        NSLog(@"第2-个任务,当前线程为:%@",[NSThread currentThread]);
    });
    dispatch_async(myQueue2, ^{
        NSLog(@"第3-个任务,当前线程为:%@",[NSThread currentThread]);
    });
    dispatch_async(myQueue2, ^{
        NSLog(@"第4-个任务,当前线程为:%@",[NSThread currentThread]);
    });
    //解释:dispatch_queue_create 创建⾃定义队列。第⼀个参数是队列标⽰符,第⼆个参数:DISPATCH_QUEUE_CONCURRENT是告诉系统,创建的是并⾏的队列。

}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
@end
 
 
 
 
 
原文地址:https://www.cnblogs.com/iQingYang/p/5194713.html