日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

多线程编程2 - NSOperation

發布時間:2024/9/30 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 多线程编程2 - NSOperation 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、NSOperation

1.簡介

NSOperation實例封裝了需要執行的操作和執行操作所需的數據,并且能夠以并發或非并發的方式執行這個操作。

NSOperation本身是抽象基類,因此必須使用它的子類,使用NSOperation子類的方式有2種:

1> Foundation框架提供了兩個具體子類直接供我們使用:NSInvocationOperation和NSBlockOperation

2> 自定義子類繼承NSOperation,實現內部相應的方法


2.執行操作

NSOperation調用start方法即可開始執行操作,NSOperation對象默認按同步方式執行,也就是在調用start方法的那個線程中直接執行。NSOperation對象的isConcurrent方法會告訴我們這個操作相對于調用start方法的線程,是同步還是異步執行。isConcurrent方法默認返回NO,表示操作與調用線程同步執行


3.取消操作

operation開始執行之后, 默認會一直執行操作直到完成,我們也可以調用cancel方法中途取消操作

[java]?view plaincopy
  • [operation?cancel];??

  • 4.監聽操作的執行

    如果我們想在一個NSOperation執行完畢后做一些事情,就調用NSOperation的setCompletionBlock方法來設置想做的事情

    [java]?view plaincopy
  • operation.completionBlock?=?^()?{??
  • ????NSLog(@"執行完畢");??
  • };??

  • 或者

    [java]?view plaincopy
  • [operation?setCompletionBlock:^()?{??
  • ????NSLog(@"執行完畢");??
  • }];??

  • 二、NSInvocationOperation

    1.簡介

    基于一個對象和selector來創建操作。如果你已經有現有的方法來執行需要的任務,就可以使用這個類


    2.創建并執行操作

    [java]?view plaincopy
  • //?這個操作是:調用self的run方法??
  • NSInvocationOperation?*operation?=?[[NSInvocationOperation?alloc]?initWithTarget:self?selector:@selector(run)?object:nil];??
  • //?開始執行任務(同步執行)??
  • [operation?start];??

  • 三、NSBlockOperation

    1.簡介

    能夠并發地執行一個或多個block對象,所有相關的block都執行完之后,操作才算完成


    2.創建并執行操作

    [java]?view plaincopy
  • NSBlockOperation?*operation?=?[NSBlockOperation?blockOperationWithBlock:^(){??
  • ????????NSLog(@"執行了一個新的操作,線程:%@",?[NSThread?currentThread]);??
  • }];??
  • ?//?開始執行任務(這里還是同步執行)??
  • [operation?start];??

  • 3.通過addExecutionBlock方法添加block操作

    [java]?view plaincopy
  • NSBlockOperation?*operation?=?[NSBlockOperation?blockOperationWithBlock:^(){??
  • ????NSLog(@"執行第1次操作,線程:%@",?[NSThread?currentThread]);??
  • }];??
  • ??
  • [operation?addExecutionBlock:^()?{??
  • ????NSLog(@"又執行了1個新的操作,線程:%@",?[NSThread?currentThread]);??
  • }];??
  • ??
  • [operation?addExecutionBlock:^()?{??
  • ????NSLog(@"又執行了1個新的操作,線程:%@",?[NSThread?currentThread]);??
  • }];??
  • ??
  • [operation?addExecutionBlock:^()?{??
  • ????NSLog(@"又執行了1個新的操作,線程:%@",?[NSThread?currentThread]);??
  • }];??
  • ??
  • //?開始執行任務??
  • [operation?start];??
  • 打印信息如下:

    [java]?view plaincopy
  • 2013-02-02?21:38:46.102?thread[4602:c07]?又執行了1個新的操作,線程:<NSThread:?0x7121d50>{name?=?(null),?num?=?1}??
  • 2013-02-02?21:38:46.102?thread[4602:3f03]?又執行了1個新的操作,線程:<NSThread:?0x742e1d0>{name?=?(null),?num?=?5}??
  • 2013-02-02?21:38:46.102?thread[4602:1b03]?執行第1次操作,線程:<NSThread:?0x742de50>{name?=?(null),?num?=?3}??
  • 2013-02-02?21:38:46.102?thread[4602:1303]?又執行了1個新的操作,線程:<NSThread:?0x7157bf0>{name?=?(null),?num?=?4}??
  • 可以看出,這4個block是并發執行的,也就是在不同線程中執行的,num屬性可以看成是線程的id


    四、自定義NSOperation

    1.簡介

    如果NSInvocationOperation和NSBlockOperation對象不能滿足需求, 你可以直接繼承NSOperation, 并添加任何你想要的行為。繼承所需的工作量主要取決于你要實現非并發還是并發的NSOperation。定義非并發的NSOperation要簡單許多,只需要重載-(void)main這個方法,在這個方法里面執行主任務,并正確地響應取消事件; 對于并發NSOperation, 你必須重寫NSOperation的多個基本方法進行實現(這里暫時先介紹非并發的NSOperation


    2.非并發的NSOperation

    比如叫做DownloadOperation,用來下載圖片

    1> 繼承NSOperation,重寫main方法,執行主任務

    DownloadOperation.h

    [java]?view plaincopy
  • #import?<Foundation/Foundation.h>??
  • @protocol?DownloadOperationDelegate;??
  • ??
  • @interface?DownloadOperation?:?NSOperation??
  • //?圖片的url路徑??
  • @property?(nonatomic,?copy)?NSString?*imageUrl;??
  • //?代理??
  • @property?(nonatomic,?retain)?id<DownloadOperationDelegate>?delegate;??
  • ??
  • -?(id)initWithUrl:(NSString?*)url?delegate:(id<DownloadOperationDelegate>)delegate;??
  • @end??
  • ??
  • //?圖片下載的協議??
  • @protocol?DownloadOperationDelegate?<NSObject>??
  • -?(void)downloadFinishWithImage:(UIImage?*)image;??
  • @end??

  • DownloadOperation.m

    [java]?view plaincopy
  • #import?"DownloadOperation.h"??
  • ??
  • @implementation?DownloadOperation??
  • @synthesize?delegate?=?_delegate;??
  • @synthesize?imageUrl?=?_imageUrl;??
  • ??
  • //?初始化??
  • -?(id)initWithUrl:(NSString?*)url?delegate:(id<DownloadOperationDelegate>)delegate?{??
  • ????if?(self?=?[super?init])?{??
  • ????????self.imageUrl?=?url;??
  • ????????self.delegate?=?delegate;??
  • ????}??
  • ????return?self;??
  • }??
  • //?釋放內存??
  • -?(void)dealloc?{??
  • ????[super?dealloc];??
  • ????[_delegate?release];??
  • ????[_imageUrl?release];??
  • }??
  • ??
  • //?執行主任務??
  • -?(void)main?{??
  • ????//?新建一個自動釋放池,如果是異步執行操作,那么將無法訪問到主線程的自動釋放池??
  • ????@autoreleasepool?{??
  • ????????//?....??
  • ????}??
  • }??
  • @end??

  • 2> 正確響應取消事件

    operation開始執行之后,會一直執行任務直到完成,或者顯式地取消操作。取消可能發生在任何時候,甚至在operation執行之前。盡管NSOperation提供了一個方法,讓應用取消一個操作,但是識別出取消事件則是我們自己的事情。如果operation直接終止, 可能無法回收所有已分配的內存或資源。因此operation對象需要檢測取消事件,并優雅地退出執行

    NSOperation對象需要定期地調用isCancelled方法檢測操作是否已經被取消,如果返回YES(表示已取消),則立即退出執行。不管是自定義NSOperation子類,還是使用系統提供的兩個具體子類,都需要支持取消。isCancelled方法本身非常輕量,可以頻繁地調用而不產生大的性能損失

    以下地方可能需要調用isCancelled:
    * 在執行任何實際的工作之前
    * 在循環的每次迭代過程中,如果每個迭代相對較長可能需要調用多次
    * 代碼中相對比較容易中止操作的任何地方

    DownloadOperation的main方法實現如下

    [java]?view plaincopy
  • -?(void)main?{??
  • ????//?新建一個自動釋放池,如果是異步執行操作,那么將無法訪問到主線程的自動釋放池??
  • ????@autoreleasepool?{??
  • ????????if?(self.isCancelled)?return;??
  • ??????????
  • ????????//?獲取圖片數據??
  • ????????NSURL?*url?=?[NSURL?URLWithString:self.imageUrl];??
  • ????????NSData?*imageData?=?[NSData?dataWithContentsOfURL:url];??
  • ??????????
  • ????????if?(self.isCancelled)?{??
  • ????????????url?=?nil;??
  • ????????????imageData?=?nil;??
  • ????????????return;??
  • ????????}??
  • ??????????
  • ????????//?初始化圖片??
  • ????????UIImage?*image?=?[UIImage?imageWithData:imageData];??
  • ??????????
  • ????????if?(self.isCancelled)?{??
  • ????????????image?=?nil;??
  • ????????????return;??
  • ????????}??
  • ??????????
  • ????????if?([self.delegate?respondsToSelector:@selector(downloadFinishWithImage:)])?{??
  • ????????????//?把圖片數據傳回到主線程??
  • ????????????[(NSObject?*)self.delegate?performSelectorOnMainThread:@selector(downloadFinishWithImage:)?withObject:image?waitUntilDone:NO];??
  • ????????}??
  • ????}??
  • } ?
  • 總結

    以上是生活随笔為你收集整理的多线程编程2 - NSOperation的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。