首页 > 代码库 > IOS多线程操作

IOS多线程操作

多线程的概念

 进程

  ·正在运行中的程序被成为进程,负责程序运行的内存分配  

  ·没一个进程都有自己独立的虚拟内存空间

 线程

  ·线程是进程中一个独立的执行路径也称之为控制单元

  ·一个进程至少包含一条线程,主线程

  ·可以将耗时的执行路径如网络请求放在其他线程中执行

 创建线程的目的就是为了开启一条新的执行路径,运行指定的代码,与主线程中的代码实现同时执行

 还要解释一个概念:多任务调度系统

  每个应用程序由操作系统分配的短暂的时间片(Timeslice)轮流使用CPU,由于CPU对每个时间片的处理速度非常快,因此,用户看来好像这些任务在同时执行的

  并发:指的是两个或者多个任务在同一时间间隔内发生,但是在任意时刻上CPU只会执行一个任务。

 IOS多线程实现的方式:

  1.NSObject多线程技术

  1>想要在某个方法中开启新的线程可以直接调用performSelectorInBackground方法来开启,selector中的方法就是要执行的操作

  2>使用performSelectorOnMainThread可以重新回到主线程中,执行UI的操作都要回到主线程中(官方的规定,如果不这么做很可能出现不可预料的问题)

  3>为了模拟线程的创建,这里采用线程休眠的方式进行模拟,相当于进行了网络请求的操作

mark:虽然在其他的线程中依然能够改变UI,但是强烈的不建议这么去做!还有一个很重要的问题是使用NSThread和NSObject的线程操作都要使用autoreleasepool,否则会出现内存泄露

 1 - (void)viewDidLoad
 2 {
 3     [super viewDidLoad];
 4     //使用performSelectorInBackground可以开启后台线程,执行selector选择器选择的方法
 5     // 2> 使用performSelectorOnMainThread可以重新回到主线程执行任务,通常用于后台线程更新界面UI时使用
 6     // 注意:在使用NSThread或者NSObject的线程方法时,一定要使用自动释放池,否则容易出现内存泄露。
 7     //提示:使用performSelectorInBackground也可以直接修改UI,但是强烈不建议使用。修改UI最好在主线程中执行
 8     [self performSelectorInBackground:@selector(testObject) withObject:nil];
 9     
10     NSLog(@"%@",[NSThread currentThread]);
11 }
12 
13 -(void)testObject
14 {
15     //自动释放池,避免出现内存泄露
16     @autoreleasepool {
17         //让当前线程睡眠2s
18         [NSThread sleepForTimeInterval:2.0f];
19         
20         NSLog(@"%@",[NSThread currentThread]);
21     }
22 }
View Code

  2.NSThread线程方法

    1.通过类方法直接产生新的线程调用方法:detachNewThreadSelctor,自动执行selector中的方法

    2.通过实例方法产生新的线程调用initWithTarget方法,需要调用实例的start方法来执行选择器的方法

    3.NSThread也需要使用autoreleasepool进行内存管理

 

+ View Code?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
- (void)viewDidLoad
{
    [super viewDidLoad];
    //NSThread类方法开启线程
//    [NSThread detachNewThreadSelector:@selector(testThread) toTarget:self withObject:nil];
    //实例方法开启线程
    NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(testThread) object:nil];
    //调用start方法才能执行selector的方法
    [thread start];
    NSLog(@"%@",[NSThread currentThread]);
}
 
-(void)testThread
{
    @autoreleasepool {
        //线程休眠,模拟耗时操作
        [NSThread sleepForTimeInterval:2.0f];
         
        NSLog(@"%@",[NSThread currentThread]);
    }
}

 

  3.使用NSOperation实现多线程

   1.第一种实现多线程的方式

    (1)新建一个队列来储存需要的操作

    (2)新建一个NSInvocationOpertaion的实例来存储一个操作

    (3)将新建的操作添加到新建的队列中去以此来按照队里的先进先出的特点进行操作的执行

  

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
@interface SWBViewController ()
{
    NSOperationQueue *_queue;
}
@end
 
@implementation SWBViewController
 
- (void)viewDidLoad
{
    [super viewDidLoad];
     
     NSLog(@"%@",[NSThread currentThread]);
     
    //1初始化队列
    _queue = [[NSOperationQueue alloc]init];
     
    //2创建线程
    NSInvocationOperation *op = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(testObject) object:nil];
    //3开启线程
    [_queue addOperation:op];
    // Do any additional setup after loading the view, typically from a nib.
}
 
- (void)testObject
{
//    [NSThread sleepForTimeInterval:2.0f];
    NSLog(@"%@",[NSThread currentThread]);
}

 

    2.使用NSBlockOperation来实现多线程操作

      (1)创建一个队列以便储存需要执行的操作

      (2)使用[NSBlockOperation blockOperationWithBlock]新建一个块代码操作,在快代码内部存储需要执行的代码

      (3)将块代码操作放入到队列中去执行同样的先进先出操作

 #mark NSOperation是使用GCD实现的一套Objective-c的API,是面向对象的线程技术提供了一些额外的方法来方便操作

      (1)[NSOpeationQueue mainQueue] addOperation ^{};//更新UI的主队列操作放在快代码执行

      (2)setMaxConcurrentOperationCount;//设置并发的最大线程数量

      (3)设置线程之间的依赖关系addDependency可以设置任务的执行顺序,同时可以跨操作队列指定依赖关系(指定依赖不能循环指定)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@interface SWBViewController ()
{
    NSOperationQueue *_queue;
}
@end
 
@implementation SWBViewController
 
- (void)viewDidLoad
{
    [super viewDidLoad];
     
     NSLog(@"%@",[NSThread currentThread]);
     
    //1初始化队列
    _queue = [[NSOperationQueue alloc]init];
     
//    //2创建线程
//    NSInvocationOperation *op = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(testObject) object:nil];
    NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
        // 让当前线程睡眠 2.0 秒
        [NSThread sleepForTimeInterval:2.0f];
        NSLog(@"%@",[NSThread currentThread]);
    }];
    //3开启线程
    [_queue addOperation:op];
    // Do any additional setup after loading the view, typically from a nib.
}

 

  

  4.GCD多线程技术

    (1)是基于C语言的底层API

    (2)使用block定义任务使用灵活方便 

    (3)提供了更多的控制能力以及操作队列中所不能使用的底层函数

  GCD的基本思想就是将操作放在队列中执行

    1.操作使用block定义

    2.队列负责调度任务执行所在的线程以及具体的执行时间

    3.队里的特点是先进先出,新添加的操作都会排在尾部。