iOS-多线程--介绍NSOperration

一个NSOperation对象就代表一个操作,对象相当于GCD中的block。

 

一、NSOperation的作用:

配合使用NSOperation和NSOperationQueue也能实现多线程。

 

二、NSOperation和NSOperationQueue实现多线程的步骤:

步骤1: 先将需要执行的操作封装到一个NSOperation对象中;

步骤2: 系统会自动将NSOperationQueue中得NSOperation取出来;

步骤3: 将取出来的NSOperation封装的操作放到一条线程中执行。

 

三、NSOperation的子类

NSOperation是个抽象类,并不具备封装操作的能力,必须使用它的子类

 

四、使用NSOperation子类的方式有3种:
1> NSInvocationOperation
2> NSBlockOperation
3> 自定义子类继承NSOperation,实现内部相应的方法
 
五、使用方式:
方式1:用NSInvocationOperation, 代码如下:
重要级别:演示
 1 - (void)viewDidLoad
 2 {
 3     [super viewDidLoad];
 4     
 5     // 创建队列
 6     NSOperationQueue *queue = [[NSOperationQueue alloc] init];
 7     
 8     // 创建操作
 9     NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(download) object:nil];
10     // operation直接调用start,是同步执行(在当前线程执行操作)
11 //    [operation start];
12     
13     // 添加操作到队列中,会自动异步执行 (如果不将operation加到队列中,直接[operation start];执行的话,就相当于调用 [self download], 不是异步执行,是在主线程执行的;添加到操作队列中,会开启一个新的线程,异步执行)
14 
15     [queue addOperation:operation];
16 }
17 
18 - (void)download
19 {
20     NSLog(@"download-----%@", [NSThread currentThread]);
21 }

 

方式2. 用NSBlockOperation,代码如下:

重要级别:了解(test1   test2 里面的是了解)

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    [self test2];
}
- (void)test2
{
    NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"---下载图片----11---%@", [NSThread currentThread]);
    }];
    
    [operation1 addExecutionBlock:^{
        NSLog(@"---下载图片----12---%@", [NSThread currentThread]);
    }];
    
    NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"---下载图片----2---%@", [NSThread currentThread]);
    }];
    
    NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"---下载图片----3---%@", [NSThread currentThread]);
    }];
    
    NSBlockOperation *operation4 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"---下载图片----4---%@", [NSThread currentThread]);
    }];
    
    // 1.创建队列
    NSOperationQueue *queue = [[NSOperationQueue alloc] init]; // 相当于GCD的全局并发队列,下面的四个操作都在新开启的线程中异步执行
    
    // 主队列
    //  NSOperationQueue *queue = [NSOperationQueue mainQueue]; // 相当于GCD的主队列,下面的四个操作都在主队列执行
    
    // 2.添加操作到队列中(自动异步执行)
    [queue addOperation:operation1];
    [queue addOperation:operation2];
    [queue addOperation:operation3];
    [queue addOperation:operation4];
}
- (void)test
{
    NSBlockOperation *operation = [[NSBlockOperation alloc] init];
    
    [operation addExecutionBlock:^{
        NSLog(@"---下载图片----1---%@", [NSThread currentThread]);
    }];
    
    [operation addExecutionBlock:^{
        NSLog(@"---下载图片----2---%@", [NSThread currentThread]);
    }];
    
    [operation addExecutionBlock:^{
        NSLog(@"---下载图片----3---%@", [NSThread currentThread]);
    }];
    
    [operation start];
    
    // 任务数量 > 1,才会开始异步执行(不然的话就是同步执行,在主线程做的)
}

 

## 下面的要掌握 ##

- (void)viewDidLoad
{
    [super viewDidLoad];

}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    [queue addOperationWithBlock:^{
        // 1.异步下载图片
        NSURL *url = [NSURL URLWithString:@"http://d.hiphotos.baidu.com/image/pic/item/37d3d539b6003af3290eaf5d362ac65c1038b652.jpg"];
        NSData *data = [NSData dataWithContentsOfURL:url];
        UIImage *image = [UIImage imageWithData:data];
        
        // 2.回到主线程,显示图片
//        [self performSelectorOnMainThread:<#(SEL)#> withObject:<#(id)#> waitUntilDone:<#(BOOL)#>];
//        dispatch_async(dispatch_get_main_queue(), ^{
//            
//        });
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            self.imageView.image = image;
        }];
    }];
}

- (void)dependency
{
    /**
     假设有A、B、C三个操作,要求:
     1. 3个操作都异步执行
     2. 操作C依赖于操作B
     3. 操作B依赖于操作A
     */
    
    // 1.创建一个队列(非主队列)
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    
    // 2.创建3个操作
    NSBlockOperation *operationA = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"A1---%@", [NSThread currentThread]);
    }];
    //    [operationA addExecutionBlock:^{
    //        NSLog(@"A2---%@", [NSThread currentThread]);
    //    }];
    //
    //    [operationA setCompletionBlock:^{
    //        NSLog(@"AAAAA---%@", [NSThread currentThread]);
    //    }];
    
    NSBlockOperation *operationB = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"B---%@", [NSThread currentThread]);
    }];
    NSBlockOperation *operationC = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"C---%@", [NSThread currentThread]);
    }];
    
    // 设置依赖
    [operationB addDependency:operationA];
    [operationC addDependency:operationB];
    
    // 3.添加操作到队列中(自动异步执行任务)
    [queue addOperation:operationC];
    [queue addOperation:operationA];
    [queue addOperation:operationB];
}

- (void)maxCount
{
    // 1.创建一个队列(非主队列,会创建新的线程)
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    
    // 2.设置最大并发(如果设置为3,则最多同时并发执行3个任务)
    queue.maxConcurrentOperationCount = 3; // 如果设置为1,那么下面的任务是在新线程中依次执行的。
    
    // 3.添加操作到队列中(自动异步执行任务,并发)
   // 下面五个操作都异步执行,如果有的操作要在方法里面执行,可以用 操作5 这种形式去实现
.
   // 操作1
NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"下载图片1---%@", [NSThread currentThread]); }];
   // 操作2 NSBlockOperation
*operation2 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"下载图片2---%@", [NSThread currentThread]); }];
   // 操作3
NSBlockOperation
*operation3 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"下载图片3---%@", [NSThread currentThread]); }];
   // 操作4
NSBlockOperation
*operation4 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"下载图片4---%@", [NSThread currentThread]); }];
   // 操作5
NSInvocationOperation
*operation5 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(download) object:nil]; [queue addOperation:operation1]; [queue addOperation:operation2]; [queue addOperation:operation3]; [queue addOperation:operation4]; [queue addOperation:operation5]; [queue addOperationWithBlock:^{ NSLog(@"下载图片5---%@", [NSThread currentThread]); }]; [queue addOperationWithBlock:^{ NSLog(@"下载图片6---%@", [NSThread currentThread]); }]; [queue addOperationWithBlock:^{ NSLog(@"下载图片7---%@", [NSThread currentThread]); }]; [queue addOperationWithBlock:^{ NSLog(@"下载图片8---%@", [NSThread currentThread]); }]; [queue addOperationWithBlock:^{ NSLog(@"下载图片9---%@", [NSThread currentThread]); }]; [queue cancelAllOperations]; }
- (void)download
{
  NSLog(@"download---%@", [NSThread currentThread]);
}
- (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // [queue cancelAllOperations]; // 取消队列中的所有任务(不可恢复) } - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView { // [queue setSuspended:YES]; // 暂停队列中的所有任务 } - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate { // [queue setSuspended:NO]; // 恢复队列中的所有任务 } - (void)baseUse { // 1.创建一个队列(非主队列) NSOperationQueue *queue = [[NSOperationQueue alloc] init]; // 2.添加操作到队列中(自动异步执行任务,并发) NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"下载图片1---%@", [NSThread currentThread]); }]; NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"下载图片2---%@", [NSThread currentThread]); }]; [queue addOperation:operation1]; [queue addOperation:operation2]; [queue addOperationWithBlock:^{ NSLog(@"下载图片3---%@", [NSThread currentThread]); }]; // 3个操作并发执行 }

 

六、操作依赖:

1. NSOperation之间可以设置依赖来保证执行顺序
    比如一定要让操作A执行完后,才能执行操作B,可以这么写:

    [operationB addDependency:operationA]; // 操作B依赖于操作A

 

2. 可以在不同queue的NSOperation之间创建依赖关系:
  

 

 

posted @ 2016-04-08 12:59  nxz_diy  阅读(260)  评论(1编辑  收藏  举报