zoukankan      html  css  js  c++  java
  • iOS开发-多线程NSOperation和NSOperationQueue

    上一篇文章稍微提及了一下NSThread的使用,NSThread能直观地控制线程对象,不过需要自己管理线程的生命周期,线程同步,用起来比较繁琐,而且比较容易出错。不过Apple给出了自己的解决方案NSOperation,它本身是抽象基类,因此必须使用它的子类,使用NSOperation子类的方式有NSInvocationOperation和NSBlockOperation两种方式,先补充一下NSThread的用法:

    NSThread获取当前线程:

    [NSThread currentThread]
    

     performSelectorInBackground可以更新UI,不建议使用:

    - (IBAction)update:(id)sender {
    
        [self performSelectorInBackground:@selector(changeImage) withObject:nil];
        
    }
    

    图片背景更新:

    -(void)changeImage{
        NSLog(@"线程执行完之后更新图片");
        self.myImageView.image=[UIImage imageNamed:[NSString stringWithFormat:@"Thread2.jpg"]];
    }
    

    NSInvocationOperation和NSBlockOperation

    这两种方式都很简单,其中NSInvocation的调用方式类似于NSThread,NSBlockOperation如果对Block有一点了解就可以,如果不明白的可以参考本人之前的Block文章 Object-C-代码块Block回顾,那么接下来的使用方式就很简单:

    先来看下NSInvocationOperation的实例化方式:

        //初始化
        NSInvocationOperation *myInvocationOperation= [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(operationTaskMethod) object:nil];
        //启动
        [myInvocationOperation start];
    

    调用方法:

    -(void)operationTaskMethod{
        NSLog(@"NSInvocationOperation初始化执行");
        
    }
    

    NSBlockOperation的方式:

      NSBlockOperation *blockOperation=[NSBlockOperation blockOperationWithBlock:^{
            NSLog(@"BlockOperation块执行");
        }];
        [blockOperation start];
    

    两种方式很方便,这个时候可以使用NSOperationQueue作为一个队列将线程包含在一起,首先定义一个NSOperationQuene:

    @property (strong,nonatomic) NSOperationQueue *myOperationQuene;
    

     这个时候需要调用:

        NSInvocationOperation *myInvocationOperation= [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(operationTaskMethod) object:nil];
        
        NSBlockOperation *blockOperation=[NSBlockOperation blockOperationWithBlock:^{
            NSLog(@"BlockOperation块执行");
        }];
    
        self.myOperationQuene=[[NSOperationQueue alloc]init];
        
        [self.myOperationQuene addOperation:myInvocationOperation];
        
        [self.myOperationQuene addOperation:blockOperation];
    

     上面最后的结果不确定,线程执行的顺序没法确定,如果想确定的按照顺序执行,需要添加一个依赖:

        [blockOperation addDependency:myInvocationOperation];
    

      添加依赖之后的,每次输出的结果一定是这样的:

    2015-02-11 07:56:13.457 ThreadDemo[657:15033] NSInvocationOperation初始化执行
    2015-02-11 07:56:13.457 ThreadDemo[657:15034] BlockOperation块执行
    

     自定义NSOperation

    每次一看到自定义,就感觉瞬间有了档次,然后参考一下前人的经验,不过网上的博客有的不好说,那感觉就是我想吃一个鸡腿,却拿到了一个鸡腿堡,需要的不需要的都要自己一起吸收。NSInvocationOperation和NSBlockOperation这两种方式不能满足业务需求,这个时候需要自定义的NSOperation,自定义的有两种分为非并发(NonConcurrent)和并发(Concurrent)两种形式,本文介绍非并发形式。

    新建一个继承自NSOperation的MyCustomOperation,然后实现一下main方法:

    //
    //  MyCustomOperation.h
    //  ThreadDemo
    //
    //  Created by keso on 15/2/11.
    //  Copyright (c) 2015年 keso. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    
    @interface MyCustomOperation : NSOperation
    
    @property (strong,nonatomic) NSString  *customdata;
    
    -(void)initData:(NSString *)data;
    
    @end

    NSOperation对象需要定期地调用isCancelled方法检测操作是否已经被取消,如果返回YES(表示已取消),则立即退出执行回收内存资源。所有NSOperation子类,一般用于代码比较容易终止的地方, 在循环的每次迭代过程中,如果每个迭代相对较长可能需要调用多次和没有执行工作之前调用。

    //
    //  MyCustomOperation.m
    //  ThreadDemo
    //
    //  Created by keso on 15/2/10.
    //  Copyright (c) 2015年 keso. All rights reserved.
    //
    
    #import "MyCustomOperation.h"
    
    @implementation MyCustomOperation
    
    - (void)initData:(NSString *)data{
        if (self ==[super init])
            _customdata= data;
    }
    - (void)main {
        @try {
            BOOL isDone = NO;
            NSLog(@"循环之前的调用");
            while (![self isCancelled] && !isDone) {
                // Do some work and set isDone to YES when finished
                NSLog(@"已经运行成功了");
                isDone=YES;
            }
        }
        @catch(...) {
            NSLog(@"出现异常,请检查代码~");
        }
    }
    
    @end
    

     如果需要调用定义的NSOPeration实例化之后Start即可:

       MyCustomOperation *customOperation=[[MyCustomOperation alloc] init];
        [customOperation start];
    

     参考资料:https://developer.apple.com/library/ios/documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationObjects/OperationObjects.html#//apple_ref/doc/uid/TP40008091-CH101-SW6

  • 相关阅读:
    ASP.NET MVC中权限控制的简单实现
    HDU1004——Let the Balloon Rise
    如何使用飞秋FeiQ实现两电脑通信(或传输文件)
    vb.net 鼠标控制
    ireport制作报表pageheader只在第一页出现的解决办法
    Keycode对照表
    leetcode第一刷_Binary Tree Zigzag Level Order Traversal
    换硬币问题
    STM32 寄存器库和固件库
    java网络编程(2)InetAddress 类及udp协议
  • 原文地址:https://www.cnblogs.com/xiaofeixiang/p/4285102.html
Copyright © 2011-2022 走看看