国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

iOS-NSOperation多線程

2019-11-14 18:33:06
字體:
來源:轉載
供稿:網友

NSOperation

一、簡介

1、使用步驟

  • 配合使用NSOperation和NSOperationQueue也能實現多線程編程

    • 先將操作封裝到一個NSOperation對象中
    • 然后將NSOperation對象添加到NSOperationQueue中
    • 系統會自動將NSOperationQueue中的NSOperation取出來
    • 將取出的NSOperation封裝的操作放到一條新線程中執行

2、具體實現方法:

第一步:封裝操作

封裝操作的時候可以使用NSOperation的子類實現,因為NSOperation是抽象類,所以不能直接使用。

  • 三種方式:

    • NSInvocationOperation
    • NSBlockOperation
    • 自定義子類繼承NSOperation,實現內部相應的方法

下面分別講解三種方式:

1、NSInvocationOperation

  • 創建NSInvocationOperation對象
- (id)initWithTarget:(id)target selector:(SEL)sel object:(id)arg;
  • 調用start方法開始執行操作
- (void)start;//一旦執行操作,就會調用target的sel方法

注意:
默認情況下,調用了start方法后并不會開一條新線程去執行操作,而是在當前線程同步執行操作
只有將NSOperation放到一個NSOperationQueue中,才會異步執行操作

2、創建NSBlockOperation對象

+ (id)blockOperationWithBlock:(void (^)(void))block;

通過addExecutionBlock:方法添加更多的操作

- (void)addExecutionBlock:(void (^)(void))block;

注意:只要NSBlockOperation封裝的操作數 > 1,就會異步執行操作

3、自定義NSOperation

自定義NSOperation的步驟很簡單

  • 重寫- (void)main方法,在里面實現想執行的任務

  • 重寫- (void)main方法的注意點

    • 自己創建自動釋放池(因為如果是異步操作,無法訪問主線程的自動釋放池)

    • 經常通過- (BOOL)isCancelled方法檢測操作是否被取消,對取消做出響應

由于取消同樣會繼續執行當前正在執行的任務, 所以耗時操作需要手動判斷是否已經取消

if (self.isCancelled) return;
第二步:添加任務奧隊列中:

// 一般情況下, 在做企業開發時候,都會定義一個全局的自定義隊列, 便于使用

NSOperationQueue *queue = [[NSOperationQueue alloc] init];
  • NSOperationQueue的作用

    • NSOperation可以調用start方法來執行任務,但默認是同步執行的
    • 如果將NSOperation添加到NSOperationQueue(操作隊列)中,系統會自動異步執行NSOperation中的操作
  • 添加操作到NSOperationQueue中

- (void)addOperation:(NSOperation *)op;- (void)addOperationWithBlock:(void (^)(void))block;

設置最大并發數

- (NSInteger)maxConcurrentOperationCount;- (void)setMaxConcurrentOperationCount:(NSInteger)cnt;

3、隊列的取消、暫停、恢復

- (void)cancelAllOperations;// 取消隊列中所有的任務的執行// 取消和暫停一樣, 是取消后面的任務, 不能取消當前正在執行的任務// 注意: 取消是不可以恢復的

提示:也可以調用NSOperation的- (void)cancel方法取消單個操作

暫停和恢復隊列

- (void)setSuspended:(BOOL)b;// YES代表暫停隊列,NO代表恢復隊列- (BOOL)isSuspended;// 只要設置隊列的suspended為YES, 那么就會暫停隊列中其它任務的執行// 也就是說不會再繼續執行沒有執行到得任務// 只要設置隊列的suspended為NO, 那么就會恢復隊列中其它任務的執行// 注意: 設置為暫停之后, 不會立即暫停// 會繼續執行當前正在執行的任務, 直到當前任務執行完畢, 就不會執行下一個任務了// 也就是說, 暫停其實是暫停下一個任務, 而不能暫停當前任務// 注意: 暫停是可以恢復的

4、依賴

NSOperation之間可以設置依賴來保證執行順序

比如一定要讓操作A執行完后,才能執行操作B,可以這么寫

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

可以在不同queue的NSOperation之間創建依賴關系

5、任務操作的監聽

可以監聽一個操作的執行完畢

- (void (^)(void))completionBlock;- (void)setCompletionBlock:(void (^)(void))block;
// 4.監聽op4什么時候執行完畢op4.completionBlock = ^{    NSLog(@"op4中所有的操作都執行完畢了");};

具體使用介紹:

實例一:

NSBlockOperation簡單使用,并添加任務

 //1. 封裝任務    NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{        // 主線程        NSLog(@"1---%@", [NSThread currentThread]);    }];    // 2.追加其它任務    // 注意: 在沒有隊列的情況下, 如果給BlockOperation追加其它任務, 那么其它任務會在子線程中執行    [op1 addExecutionBlock:^{        NSLog(@"2---%@", [NSThread currentThread]);    }];    [op1 addExecutionBlock:^{        NSLog(@"3---%@", [NSThread currentThread]);    }];    // 3.啟動任務    [op1 start];

實例二:

NSInvocationOperation的簡單使用

// 1.封裝任務NSInvocationOperation *op1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run) object:nil];// 2.要想執行任務必須調用start[op1 start];

實例三:

創建各種操作并添加到隊列里面.

// 1.創建隊列    /*     GCD中有哪些隊列:     并發: 自己創建, 全局     串行: 自己創建, 主隊列     NSOperationQueue:     主隊列: mainQueue     自己創建: 會在子線程中執行     */    NSOperationQueue *queue = [[NSOperationQueue alloc] init];    // 2.創建任務    // 只要是自己創建的隊列, 就會在子線程中執行    // 而且默認就是并發執行    //第一種    NSInvocationOperation *op1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(download1) object:nil];    //第二種    NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{        NSLog(@"2 == %@", [NSThread currentThread]);    }];    // 注意: 如果是使用block來封裝任務, 那么有一種更簡便的方法    // 只要利用隊列調用addOperationWithBlock:方法, 系統內部會自動封裝成一個NSBlockOperation然后再添加到隊列中    //第三種    [queue addOperationWithBlock:^{        NSLog(@"3 == %@", [NSThread currentThread]);    }];    // 3.添加任務到隊列中    // 只要將任務添加到隊列中, 隊列會自動調用start    [queue addOperation:op1];    [queue addOperation:op2];

實例四:

最大執行數量

NSOperationQueue *queue = [[NSOperationQueue alloc] init];// 自己創建的隊列默認是并發,如果設置maxConcurrentOperationCount = 1,就是串行// 注意: 不能設置為0, 如果設置為0就不行執行任務/// 默認情況下maxConcurrentOperationCount = -1,是并行// 在開發中并發數最多盡量不要超過5~6條queue.maxConcurrentOperationCount = 0;

實例四:

線程間通訊

 // 1.創建一個隊列    // 一般情況下, 在做企業開發時候, 都會定義一個全局的自定義隊列, 便于使用    NSOperationQueue *queue = [[NSOperationQueue alloc] init];    // 2.添加一個操作下載第一張圖片    __block UIImage *image1 = nil;    NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{        NSURL *url  = [NSURL URLWithString:@"http://imgcache.mysodao.com/img2/M04/8C/74/CgAPDk9dyjvS1AanAAJPPRypnFA573_700x0x1.JPG"];        NSData *data = [NSData dataWithContentsOfURL:url];        image1 = [UIImage imageWithData:data];    }];    // 3.添加一個操作下載第二張圖片    __block UIImage *image2 = nil;     NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{        NSURL *url  = [NSURL URLWithString:@"http://imgcache.mysodao.com/img1/M02/EE/B5/CgAPDE-kEtqjE8CWAAg9m-Zz4qo025-22365300.JPG"];        NSData *data = [NSData dataWithContentsOfURL:url];        image2 = [UIImage imageWithData:data];    }];    // 4.添加一個操作合成圖片    NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{        UIGraphicsBeginImageContext(CGSizeMake(200, 200));        [image1 drawInRect:CGRectMake(0, 0, 100, 200)];        [image2 drawInRect:CGRectMake(100, 0, 100, 200)];        UIImage *res = UIGraphicsGetImageFromCurrentImageContext();        UIGraphicsEndImageContext();        // 5.回到主線程更新UI        [[NSOperationQueue mainQueue] addOperationWithBlock:^{            self.imageView.image = res;        }];    }];    // 6.添加依賴    [op3 addDependency:op1];    [op3 addDependency:op2];    // 7.添加操作到隊列中    [queue addOperation:op1];    [queue addOperation:op2];    [queue addOperation:op3];

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 鹤庆县| 大兴区| 柞水县| 同江市| 彰化市| 柘荣县| 含山县| 文水县| 苗栗县| 铜鼓县| 新疆| 桐乡市| 怀仁县| 星子县| 合作市| 郴州市| 阿坝县| 文山县| 喀什市| 平顶山市| 鄄城县| 秦安县| 湖南省| 句容市| 阿合奇县| 缙云县| 平湖市| 莲花县| 中江县| 余干县| 阳谷县| 屏山县| 峨边| 元江| 陇川县| 车险| 五莲县| 扶风县| 勃利县| 即墨市| 宜都市|