• iOS多线程之9.自定义NSOperation


      本文主要讲如何自定义NSOperation,以及自定义NSOperation的一些注意事项,以下载图片为例。

    新建一个类,继承于NSOperation。

    CustomOperation.h
    代码

    #import <Foundation/Foundation.h>
    #import <UIKit/UIKit.h>
    
    @interface CustomOperation : NSOperation
    
    @property (nonatomic, copy) NSString *strURL;
    @property (nonatomic, copy) void (^DownLoadImageBLock)(UIImage *image);
    
    @end
    

    CustomOperation.m

    #import "CustomOperation.h"
    
    @implementation CustomOperation
    
    // 1.实现Main方法
    - (void)main {
        // 2.新建一个自动释放池
        @autoreleasepool {
            // 3.正确响应取消事件
            if (self.isCancelled)  return;
            
            NSURL *url = [NSURL URLWithString:self.strURL];
            NSData *data = [NSData dataWithContentsOfURL:url];
            if (self.isCancelled) {
                url = nil;
                data = nil;
            }
            
            UIImage *image = [UIImage imageWithData:data];
            if (self.isCancelled) {
                image = nil;
                return;
            }
            // 4.把图片传回主线程
            dispatch_async(dispatch_get_main_queue(), ^{
                 //5. 用block传值
                if (self.DownLoadImageBLock) {
                    self.DownLoadImageBLock(image);
                }
            });
          
        }
    }
      // 6. dealloc
    -(void)dealloc {
        NSLog(@"operation-------dealloc");
    }
    

    分析:1.自定义NSOperation都要实现Main方法,在这个方法里写要NSOperation执行的耗时操作。
    2.新建一个自动释放池。如果是异步操作,不能访问主线程的自动释放池,所以要新建一个。
    3.正确响应取消事件。在每一个耗时操作之前,都要判断此操作是否被取消。如果取消了,就不往下执行了。因为我们有时候需要先取消下载,例如滑动tableView的时候,等不滑动了,再继续,增加UI流畅度。
    4.把图片传回主线程。主线程回调,因为下载完的数据肯定是要操作UI的,AFNetworking就是这样干的。
    5.用block传值。传值之前判断是否存在此block,这和代理传值之前判断代理是否响应了代理里的方法是一个道理。
    6.dealloc方法,监测一下有没有正确释放内存。

    使用自定义NSOperation

    代码

    // 点击屏幕下载图片
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    
        // 1.创建一个CustomOperation对象
        CustomOperation *operation1 = [[CustomOperation alloc] init];
        // 2.为URL赋值
        operation1.strURL = @"http://h.hiphotos.baidu.com/zhidao/pic/item/6d81800a19d8bc3ed69473cb848ba61ea8d34516.jpg";
        // 3.处理block传回来的结果
        operation1.DownLoadImageBLock = ^(UIImage *image) {
            self.imageView1.image = image;
        };
        // 4.创建一个CustomOperation对象
        CustomOperation *operation2 = [[CustomOperation alloc] init];
        operation2.strURL = @"http://h.hiphotos.baidu.com/zhidao/pic/item/0eb30f2442a7d9334f268ca9a84bd11372f00159.jpg";
        operation2.DownLoadImageBLock = ^(UIImage *image) {
            self.imageView2.image = image;
        };
        // 5.创建一个队列
        NSOperationQueue *queue = [[NSOperationQueue alloc] init];
        // 6.把操作放入队列中
        [queue addOperation:operation1];
        [queue addOperation:operation2];
    }
    

    效果

    分析1. 这一步和使用系统提供的NSOperation没有区别。
    2.为自定义的NSOperation提供下载地址。
    3.处理下载之后的数据。由于在自定义的NSOperation中已经是主线程回调了,所以就可以直接操作UI了。
    4.同上。
    5.创建一个队列。
    6..把操作放入队列中。
      自定义一个NSOperation就是这么简单,我们只要重写main方法就可以,传值的方式有多种,如果大家不习惯block,也可以用代理,都能达到效果。但是block的可读性更高,因为代码都写在一起,好找。稍后我会向git上传一个项目,是列表页下载图片,用自定义NSOperation写的,有兴趣的可以看看。

  • 相关阅读:
    牛客网Java刷题知识点之什么是进程、什么是线程、什么是多线程、多线程的好处和弊端、多线程的创建方式、JVM中的多线程解析、多线程运行图解
    [转]OData的初步认识 OData v4 Client Code Generator
    [转]OData – the best way to REST–实例讲解ASP.NET WebAPI OData (V4) Service & Client
    [转]Calling an OData Service From a .NET Client (C#)
    [转]Upgrading to Async with Entity Framework, MVC, OData AsyncEntitySetController, Kendo UI, Glimpse & Generic Unit of Work Repository Framework v2.0
    [转]ASP.NET web API 2 OData enhancements
    [转]Web Api系列教程第2季(OData篇)(二)——使用Web Api创建只读的OData服务
    [转]Creating an OData v3 Endpoint with Web API 2
    [转]Getting started with ASP.NET Web API OData in 3 simple steps
    [转]使用ASP.NET Web API 2创建OData v4 终结点
  • 原文地址:https://www.cnblogs.com/doujiangyoutiao/p/6082275.html
Copyright © 2020-2023  润新知