NSOperation简单使用01

 

NSOperation(操作) 是一个抽象类 不能直接使用;

NSOperation 有两个直接子类;NSInvocationOperation(调用)和NSBlockOperation(代码块)

NSOperation是对GCD的进一步封装,相比于GCD而言,GCD使用方便,适用于简单的线程操作,不能控制

NSOperation是可以控制的各个操作之间有依赖关系,可以 - (void)start; - (void)cancel;

添加/移除操作依赖

- (void)addDependency:(NSOperation *)op;

- (void)removeDependency:(NSOperation *)op;

 

操作必定执行main方法

- (void)main;

 

实例代码:

- (void)viewDidLoad {

    [super viewDidLoad];

    // NSOperation本质是对GCD的封装

    //    NSOperation

    NSInvocationOperation *operation1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(testLongs) object:nil];

    // 默认情况下调用start方法之后不会开启新的线程,只会在当前线程中执行操作

    [operation1 start];

    // 只有将操作放入到操作队列中(NSOperationQueue)中,才会异步执行操作

    

}

- (void)testLongs {

    NSURL *url = [NSURL URLWithString:@"http://127.0.0.1/new/images/angle00.png"];

    NSData *data = [NSData dataWithContentsOfURL:url];

    UIImage *image = [UIImage imageWithData:data];

    NSLog(@"%@",[NSThread currentThread]);

    self.imageIcon1.image = image;

}

- (UIImageView *)imageIcon1{

    

    if (_imageIcon1 == nil) {

        _imageIcon1 = [[UIImageView alloc] initWithFrame: CGRectMake(20, 20, 200, 200)];

        [self.view addSubview:_imageIcon1];

        

    }

    return _imageIcon1;

}

 

 

// 只有将操作放入到操作队列中(NSOperationQueue)中,才会异步执行操作

 

[[NSBlockOperation blockOperationWithBlock:^{

    NSData *data = [NSData dataWithContentsOfURL:self.url];

    UIImage *image = [UIImage imageWithData:data];

    NSLog(@"%@",[NSThread currentThread]);

    self.imageIcon2.image = image;

}] start];

 

NSBlockOperation 实例:

 

NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{

    

    NSLog(@"1----%@",[NSThread currentThread]);

    NSData *data = [NSData dataWithContentsOfURL:self.url];

    UIImage *image = [UIImage imageWithData:data];

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

        self.imageIcon1.image = image;

    });

}];

// 添加多个操作

[blockOperation addExecutionBlock:^{

    NSLog(@"2----%@",[NSThread currentThread]);

    NSData *data = [NSData dataWithContentsOfURL:self.url];

    UIImage *image = [UIImage imageWithData:data];

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

        self.imageIcon2.image = image;

    });

}];

[blockOperation addExecutionBlock:^{

    NSLog(@"3----%@",[NSThread currentThread]);

    NSData *data = [NSData dataWithContentsOfURL:self.url];

    UIImage *image = [UIImage imageWithData:data];

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

        self.imageIcon3.image = image;

    });

}];

// 只要NSBlockOperation中封装的操作数 > 1 调用star方法后,会开启多条线程

多个任务是同时执行的

// 只要NSBlockOperation中封装的操作数 == 1 时 调用start方法后不会开启新线程(只在主线程中执行操作)

[blockOperation start];

 

 

 

 

*操作队列:(NSOperationQueue)

 

实例代码:

 

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

    

    // 创建操作

    NSBlockOperation *blockOp = [NSBlockOperation blockOperationWithBlock:^{

        NSLog(@"1---%@",[NSThread currentThread]);

        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

            self.imageIcon1.image = [self imageWithURL:self.url];

        });

    }];

    [blockOp addExecutionBlock:^{

        NSLog(@"2---%@",[NSThread currentThread]);

        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

            self.imageIcon2.image = [self imageWithURL:self.url];

        });

    }];

    [blockOp addExecutionBlock:^{

        NSLog(@"3---%@",[NSThread currentThread]);

        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

            self.imageIcon3.image = [self imageWithURL:self.url];

        });

    }];

    [blockOp addExecutionBlock:^{

        NSLog(@"4---%@",[NSThread currentThread]);

        // [self imageWithURL:self.url];

    }];

    [self.myQueue addOperation:blockOp];

    //-------------该操作封装的任务是异步执行的,

    /*

     NSOperation[1664:217071] 4---<NSThread: 0x7fe2b3c65430>{number = 5, name = (null)}

     NSOperation[1664:217072] 2---<NSThread: 0x7fe2b3c65020>{number = 3, name = (null)}

     NSOperation[1664:217074] 1---<NSThread: 0x7fe2b3e10130>{number = 2, name = (null)}

     NSOperation[1664:217073] 3---<NSThread: 0x7fe2b3e0a7d0>{number = 4, name = (null)}

     NSOperation[1664:217072] 操作完成后的回调代码,,鸡肋

     */

    

    blockOp.completionBlock = ^{

        NSLog(@"操作完成后的回调代码,,鸡肋");

    };

}

 

- (UIImage *)imageWithURL:(NSURL *)url{

    NSData *data = [NSData dataWithContentsOfURL:url];

    return [UIImage imageWithData:data];

}

/**

 *  创建一个队列 通过getter方法获取

 */

- (NSOperationQueue *)myQueue{

    if (_myQueue == nil) {

        _myQueue = [[NSOperationQueue alloc] init];

    }

    return _myQueue;

}

 

- (UIImageView *)imageIcon1{

    

    if (_imageIcon1 == nil) {

        _imageIcon1 = [[UIImageView alloc] initWithFrame: CGRectMake(20, 20, 200, 200)];

        [self.view addSubview:_imageIcon1];

        

    }

    return _imageIcon1;

}

- (UIImageView *)imageIcon2{

    

    if (_imageIcon2 == nil) {

        _imageIcon2 = [[UIImageView alloc] initWithFrame: CGRectMake(20, 200, 200, 200)];

        [self.view addSubview:_imageIcon2];

        

    }

    return _imageIcon2;

}

 

- (NSURL *)url{

    if (_url == nil) {

        NSString *str = @"http://127.0.0.1/new/images/angle00.png";

        _url = [NSURL URLWithString:str];

    }

    return _url;

}

 

- (UIImageView *)imageIcon3{

    

    if (_imageIcon3 == nil) {

        _imageIcon3= [[UIImageView alloc] initWithFrame: CGRectMake(20, 400, 200, 200)];

        [self.view addSubview:_imageIcon3];

        

    }

    return _imageIcon3;

}

 

*操作的执行顺序是不确定的:

如果要限制操作的执行顺序,可以添加操作依赖

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

    __weak typeof(self) wself = self;

    NSBlockOperation *blockOp1 = [NSBlockOperation blockOperationWithBlock:^{

        UIImage *image = [self imageWithURL:self.url];

        dispatch_async(dispatch_get_main_queue(), ^{

            wself.imageIcon1.image = image;

        });

    }];

    NSBlockOperation *blockOp2 = [NSBlockOperation blockOperationWithBlock:^{

        UIImage *image = [self imageWithURL:self.url];

        dispatch_async(dispatch_get_main_queue(), ^{

            wself.imageIcon2.image = image;

        });

    }];

    NSBlockOperation *blockOp3 = [NSBlockOperation blockOperationWithBlock:^{

        UIImage *image = [self imageWithURL:self.url];

        dispatch_async(dispatch_get_main_queue(), ^{

            wself.imageIcon3.image = image;

        });

    }];

    // blockOp2的执行依赖于blockOp1 (blockOp1执行完后才会执行blockOp2)

    [blockOp2 addDependency:blockOp1];

    [blockOp3 addDependency:blockOp2];

    

    [self.myQueue addOperation:blockOp1];

    [self.myQueue addOperation:blockOp2];

    [[NSOperationQueue mainQueue] addOperation:blockOp3];

    //----------------

    // 添加操作依赖注意事项

    /**

     *  1> 需要将操作依赖放在添加操作到队列之前,不然不起丝毫作用

     *

     *  2> 不要循环添加依赖,后果自负

     *

     *  3> 添加到不同队列中的操作,操作依然有效

     *

     *  4> 向队列中添加操作的顺序和操作依赖没有丝毫关系

     *

     *  5> 如果需要对操作做依赖,必须将任务封装在操作中,NSOperation中的操作从某种意义上代替的GCD中的串行队列,

     *      但是GCD效率更高,不过NSoperation是可以控制的

     */

}

 

 

*操作队列:

 

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

    

    NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{

        

    }];

    // 操作队列

    // 创建一个非主队列,

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

    // 设置最大并发数量

    [queue setMaxConcurrentOperationCount:6];

    //    queue.maxConcurrentOperationCount = 4;

    

    // 将操作添加到队列中

    [queue addOperation:blockOperation];

    

    // 取消所有操作 当收到内存警告的时候可以取消所的操作, 取消操作后不会恢复

    [queue cancelAllOperations];

    

    // 取消单个操作

    [blockOperation cancel];

    

    // 暂停/继续所有操作

    [queue setSuspended:YES];

    //    queue.suspended = YES;

    queue.suspended = NO;

    /**

     *  为什么要取消操作,什么情况下要取消操作

     *

     *  1> 为了用户,为了用户体验,保证程序的流畅

     *

     *  2> 为了管理内存,方式系统在低内存情况下杀死app

     */

}

 

// 接收到内存警告的时候果断取消队列中的所有操作

- (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

    

    //    [queue cancelAllOperations]; // 取消队列中的所有任务(不可恢复)

}

// 开始滚动的时候暂停队列中的任务.

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView

{

    //    [queue setSuspended:YES]; // 暂停队列中的所有任务

}

// 滚动结束的时候恢复队列中的任务.

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate

{

    //    [queue setSuspended:NO]; // 恢复队列中的所有任务

}

 

*线程间通信:

0> 子线程下载图片(数据),主线程更新UI

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

    

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

    //    __weak typeof(self) weakSelf = self;

    NSBlockOperation *blockOp = [NSBlockOperation blockOperationWithBlock:^{

        //        UIImage *image = [self imageWithURL:self.url];

        NSData *data = [NSData dataWithContentsOfURL:self.url];

        UIImage *image = [UIImage imageWithData:data];

        [[NSOperationQueue mainQueue] addOperationWithBlock:^{

            self.imageIcon1.image = image;

        }];

        

    }];

    [queue addOperation:blockOp];

    

}

 

  

转载于:https://www.cnblogs.com/wolfman4secret/p/4626787.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值