美文网首页赏味不足iOS开发记录IOS
iOS开发多线程篇之NSOperation

iOS开发多线程篇之NSOperation

作者: lyking | 来源:发表于2016-07-06 11:18 被阅读163次

    一、NSOperation简介


    1、简单说明

    • NSOperation的作⽤:配合使用NSOperation和NSOperationQueue也能实现多线程编程
    • NSOperation和NSOperationQueue实现多线程的具体步骤:

    (1)先将需要执行的操作封装到一个NSOperation对象中
    (2)然后将NSOperation对象添加到NSOperationQueue中
    (3)系统会⾃动将NSOperationQueue中的NSOperation取出来
    (4)将取出的NSOperation封装的操作放到⼀条新线程中执⾏

    2、NSOperation的子类

    • NSOperation是个抽象类,并不具备封装操作的能力,必须使⽤它的子类
    • 使用NSOperation⼦类的方式有3种:

    (1)NSInvocationOperation
    (2)NSBlockOperation
    (3)自定义子类继承NSOperation,实现内部相应的⽅法

    3、执行

    执行一个operation有两种方:

    • 第一种是自己手动的调用start这个方法,这种方法调用会在当前调用的线程进行同步执行,所以在主线程里面自己一定要小心的调用,不然就会把主线程给卡死,还不如直接用GCD呢。
    • 第二种是将operation添加到operationQueue中去,这个也是我们用得最多的也是提倡的方法。NSOperationQueue会在我们添加进去operation的时候尽快进行执行。当然如果NSOperationQueue的maxConcurrentOperationCount如果设置为1的话,进相当于FIFO了。

    二、 操作


    1、NSInvocationOperation子类

    注意:操作对象默认在主线程中执行,只有添加到队列中才会开启新的线程。即默认情况下,如果操作没有放到队列中queue中,都是同步执行。只有将NSOperation放到一个NSOperationQueue中,才会异步执行操作

    1.1 创建并执行操作

     NSInvocationOperation *operation=[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run) object:nil];
    [operation start];//开始执行任务(同步执行)
    

    1.2 事件响应

    - (void)run {
        NSLog(@"%@",[NSThread currentThread]);
    }
    

    1.3 执行结果

    **2016-07-06 10:15:32.593 ****类库****[6716:2832599] <NSThread: 0x166456b0>{number = 1, name = main}**
    

    2、NSBlockOperation子类

    2.1 创建并执行操作

    NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^(){  
        NSLog(@"执行了一个新的操作,线程:%@", [NSThread currentThread]);  
    }];  
     // 开始执行任务(这里还是同步执行)  
    [operation start]; 
    

    2.2.通过addExecutionBlock方法添加block操作

    NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^(){  
    NSLog(@"执行第1次操作,线程:%@", [NSThread currentThread]);  
    }];  
    
    [operation addExecutionBlock:^() {  
    NSLog(@"又执行了1个新的操作,线程:%@", [NSThread currentThread]);  
    }];  
    
    [operation addExecutionBlock:^() {  
    NSLog(@"又执行了1个新的操作,线程:%@", [NSThread currentThread]);  
    }];  
    
    [operation addExecutionBlock:^() {  
    NSLog(@"又执行了1个新的操作,线程:%@", [NSThread currentThread]);  
    }];  
    
    // 开始执行任务  
    [operation start];  
    

    结果

    **2016-07-06 10:28:12.476 ****类库****[6730:2835101] 2****又执行了****1****个新的操作,线程:****<NSThread: 0x17d3ca10>{number = 2, name = (null)}**
    **2016-07-06 10:28:12.476 ****类库****[6730:2835035] 1****执行第****1****次操作,线程:****<NSThread: 0x17d19150>{number = 1, name = main}**
    **2016-07-06 10:28:12.477 ****类库****[6730:2835101] 3****又执行了****1****个新的操作,线程:****<NSThread: 0x17d3ca10>{number = 2, name = (null)}**
    **2016-07-06 10:28:12.477 ****类库****[6730:2835035] 4****又执行了****1****个新的操作,线程:****<NSThread: 0x17d19150>{number = 1, name = main}**
    

    可以看出,这4个block是并发执行的,也就是在不同线程中执行的

    3、NSOperationQueue

    NSOperationQueue的作⽤:

    (1) NSOperation可以调⽤start⽅法来执⾏任务,但默认是同步执行的
    (2) 如果将NSOperation添加到NSOperationQueue(操作队列)中,系统会自动异步执行NSOperation中的操作
    (3) 添加操作到NSOperationQueue中,自动执行操作,自动开启线程

    3.1 创建队列

    NSOperationQueue * queue = [[NSOperationQueue alloc] init];
    

    3.2 将操作添加到队列当中

    //第一种方式 
    [queue addOperation:operation1];
    
    //第二种方式
    [queue addOperationWithBlock:^{    
        NSLog(@"NSBlockOperation%@",[NSThread currentThread]);
    }];
    

    3.3 示例

    NSOperationQueue * queue = [[NSOperationQueue alloc] init];
    
    
    NSInvocationOperation *operation1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run) object:nil];
    
    NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^(){
        NSLog(@"2:NSBlockOperation:%@", [NSThread currentThread]);
    }];
    
    [operation2 addExecutionBlock:^() {
        NSLog(@"3:NSBlockOperation:%@", [NSThread currentThread]);
    }];
    
    [operation2 addExecutionBlock:^() {
        NSLog(@"4:NSBlockOperation:%@", [NSThread currentThread]);
    }];
    
    [operation2 addExecutionBlock:^() {
        NSLog(@"5:NSBlockOperation:%@", [NSThread currentThread]);
    }];  
    
    [queue addOperation:operation1];
    [queue addOperation:operation2];
    
    
    
    - (void)run {
        NSLog(@"1:NSInvocationOperation:%@", [NSThread currentThread]);
    }
    

    结果:

    **2016-07-06 11:03:15.197 ****类库****[6736:2840181] 1:NSInvocationOperation****:****<NSThread: 0x16542de0>{number = 2, name = (null)}**
    **2016-07-06 11:03:15.198 ****类库****[6736:2840176] 2:NSBlockOperation****:****<NSThread: 0x16521a80>{number = 3, name = (null)}**
    **2016-07-06 11:03:15.198 ****类库****[6736:2840176] 3:NSBlockOperation****:****<NSThread: 0x16521a80>{number = 3, name = (null)}**
    **2016-07-06 11:03:15.198 ****类库****[6736:2840176] 4:NSBlockOperation****:****<NSThread: 0x16521a80>{number = 3, name = (null)}**
    **2016-07-06 11:03:15.200 ****类库****[6736:2840176] 5:NSBlockOperation****:****<NSThread: 0x16521a80>{number = 3, name = (null)}**
    

    可以看出任务是异步并发执行的

    相关文章

      网友评论

        本文标题:iOS开发多线程篇之NSOperation

        本文链接:https://www.haomeiwen.com/subject/uflkjttx.html