码迷,mamicode.com
首页 > 编程语言 > 详细

多线程005------NSOperation

时间:2016-05-12 20:03:43      阅读:240      评论:0      收藏:0      [点我收藏+]

标签:

1. NSOperation简介

优点

  • 是OC语言中基于GCD的面向对象的封装

  • 使用起来比GCD更加简单(面向对象)

  • 供了一些用GCD不好实现的功能

  • 苹果推荐使用,使用NSOperation不用关心线程以及线程的生命周期

特点

NSOperation是一个抽象类

  1. 不能直接使用(方法没有实现)
  2. 约束子类都具有共同的属性和方法

NSOperation的子类

  1. NSInvocationOperation
  2. NSBlockOperation
  3. 自定义operation

NSOperationQueue 队列

与GCD中的队列类似的概念

  • 并发队列
  • 异步执行

2. NSInvocationOperation使用方法

  • 执行操作
//创建操作
NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:
@selector(downloadFile:) object:@"fileName"];
//在当前线程执行方法(开始执行操作)
[op start];

此方法不开线程

  • 把操作添加到队列(并开始异步执行)
//创建操作
NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector: @selector(downloadFile:) object:@"fileName"];
//将操作添加到队列,会自动异步调用方法
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperation:op];
- (void)downloadFile:(id)object{ NSLog(@"下载:%@----线程:%@",object,[NSThread currentThread]);
}

开线程,异步执行

  • 添加多个操作到队列
- (void)opDemo3 {
    NSOperationQueue *q = [[NSOperationQueue alloc] init];

    for (int i = 0; i < 10; ++i) {
        NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadImage:) object:@(i)];

        [q addOperation:op];
    }
}
}

开启多个线程,不会顺序执行---》GCD并发队列,异步执行

3. NSBlockOperation代码演示

  • NSBlockOperation
//队列
NSOperationQueue *queue = [[NSOperationQueue alloc] init]; for (int i = 0; i < 10; i++) {
//操作
NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"down %d %@",i,[NSThread currentThread]); }];
[queue addOperation:op]; }
  • NSOperationQueue添加block的operation代码更简练
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
for (int i = 0; i < 10; i++) {
[queue addOperationWithBlock:^{
NSLog(@"down %d %@",i,[NSThread currentThread]); }];
}
  • 全局操作队列(controller的全局),调度所有的异步操作 定义属性
@property (nonatomic, strong) NSOperationQueue *queue; 懒加载队列
- (NSOperationQueue *)queue{
if (_queue == nil) {
_queue = [[NSOperationQueue alloc] init]; }
return _queue; }
for (int i = 0; i < 10; i++) {
[self.queue addOperationWithBlock:^{
NSLog(@"down %d %@",i,[NSThread currentThread]); }];
}
  • 监听操作完成
[op1 setCompletionBlock:^{
NSLog(@"....."); }];

4. 线程间通讯

- (void)opDemo6 {
    NSOperationQueue *q = [[NSOperationQueue alloc] init];

    [q addOperationWithBlock:^{
        NSLog(@"耗时操作 %@", [NSThread currentThread]);

        // 主线程更新 UI
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            NSLog(@"更新 UI %@", [NSThread currentThread]);
        }];
    }];
}

5. 其他特性以及用法

全局队列

/// 全局操作队列,统一管理所有的异步操作
@property (nonatomic, strong) NSOperationQueue *queue;

- (NSOperationQueue *)queue {
    if (_queue == nil) {
        _queue = [[NSOperationQueue alloc] init];
    }
    return _queue;
}

此方式成为懒加载

最大并发数

/// MARK: - 最大并发操作数
- (void)opDemo1 {

    // 设置同时并发操作数
    self.queue.maxConcurrentOperationCount = 2;

    NSLog(@"start");

    for (int i = 0; i < 10; ++i) {
        NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
            [NSThread sleepForTimeInterval:1.0];
            NSLog(@"%@ %d", [NSThread currentThread], i);
        }];

        [self.queue addOperation:op];
    }
}

GCD不能指定最大线程数

暂停 & 继续

/// MARK: - 暂停 & 继续
- (IBAction)pauseAndResume {

    if (self.queue.operationCount == 0) {
        NSLog(@"没有操作");
        return;
    }

    // 暂停或者继续
    self.queue.suspended = !self.queue.isSuspended;

    if (self.queue.isSuspended) {
        NSLog(@"暂停 %tu", self.queue.operationCount);
    } else {
        NSLog(@"继续 %tu", self.queue.operationCount);
    }
}
  • 队列挂起,当前"没有完成的操作",是包含在队列的操作数中的
  • 队列挂起,不会影响已经执行操作的执行状态
  • 对列一旦被挂起,再添加的操作不会被调度

取消全部操作

/// MARK: - 取消所有操作
- (IBAction)cancelAll {
    if (self.queue.operationCount == 0) {
        NSLog(@"没有操作");
        return;
    }

    // 取消对列中的所有操作,同样不会影响到正在执行中的操作!
    [self.queue cancelAllOperations];

    NSLog(@"取消全部操作 %tu", self.queue.operationCount);
}
  • 取消队列中所有的操作
  • 不会取消正在执行中的操作
  • 不会影响队列的挂起状态

依赖关系

/// MARK: - 依赖关系
- (void)dependency {

    NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"登录 %@", [NSThread currentThread]);
    }];
    NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"付费 %@", [NSThread currentThread]);
    }];
    NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"下载 %@", [NSThread currentThread]);
    }];
    NSBlockOperation *op4 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"通知用户 %@", [NSThread currentThread]);
    }];

    [op2 addDependency:op1];
    [op3 addDependency:op2];
    [op4 addDependency:op3];
    // 注意不要循环依赖
//    [op1 addDependency:op4];

    [self.queue addOperations:@[op1, op2, op3] waitUntilFinished:NO];
    [[NSOperationQueue mainQueue] addOperation:op4];

    NSLog(@"come here");
}

用来控制任务之间执行的顺序

6. NSOperation与GCD的对比

GCD

  • 将任务(block)添加到队列(串行/并发/主队列),并且指定任务执行的函数(同步/异步)
  • GCD是底层的C语言构成的API
  • iOS 4.0 推出的,针对多核处理器的并发技术
  • 在队列中执行的是由 block 构成的任务,这是一个轻量级的数据结构
  • 要停止已经加入 queue 的 block 需要写复杂的代码
  • 需要通过 Barrier 或者同步任务设置任务之间的依赖关系
  • 只能设置队列的优先级
  • 高级功能: 一次性 once 延迟操作 after 调度组

NSOperation

  • 核心概念:把操作(异步)添加到队列(全局的并发队列)
  • OC 框架,更加面向对象,是对 GCD 的封装
  • iOS 2.0 推出的,苹果推出 GCD 之后,对 NSOperation 的底层全部重写
  • Operation作为一个对象,为我们提供了更多的选择
  • 可以随时取消已经设定要准备执行的任务,已经执行的除外
  • 可以跨队列设置操作的依赖关系
  • 可以设置队列中每一个操作的优先级
  • 高级功能: 最大操作并发数(GCD不好做) 继续/暂停/全部取消 跨队列设置操作的依赖关系



多线程005------NSOperation

标签:

原文地址:http://blog.csdn.net/wangjunling888/article/details/51353636

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!