麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

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

iOSNSOperation非并發執行

2019-11-14 19:22:15
字體:
來源:轉載
供稿:網友
NSOperation提供了一種面向對象的方法來封裝任務。NSOperation可以單獨執行,也可以放到NSOperationQueue中執行。
 
NSOperation是虛基類不能直接使用,但Cocoa提供了兩個簡單的子類NSBlockOperation和NSInvocationOperation。NSBlockOperation是將任務封裝到block對象中,NSInvocationOperation 是將任務封裝到selector。
 
NSBlockOperation 直接使用
- (void)startOperation
{
    NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"NSBlockOperation Test");
    }];
 
    [operation start];
}
 
調用start方法開始執行任務,NSOperation的實例方法cancel可以取消正在執行的任務,這比GCD有優勢(GCD中不提供取消任務的功能)。但是這里并不是我們想像的這么簡單調用一個cancel方法就夠了,看下面代碼:
- (void)startOperation
{
    NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
        while (1) {
            NSLog(@"Test operation cancel funcation");
        }
    }];
   
    [operation start];
    [operation cancel];
}
 
start方法調用后while循環會一直執行,之后調用cancel方法,while循環會停止嗎?答案是不會的,因為cancel方法就不會被執行,當前線程一直卡在block任務中。
你可能會想我在start方法前設置0.01s延遲后調用實例的cancel方法呢?看下面代碼:
- (void)startOperation
{
    NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
        while (1) {
            NSLog(@"Test operation cancel funcation");
        }
    }];
 
    self.operation = operation;
    [self performSelector:@selector(cancelOperation) withObject:nil afterDelay:0.01f];
 
    [operation start];
}
 
- (void)cancelOperation
{
    [self.operation cancel];
}
 
實際運行發現cancelOperation方法根本就不會調用,這是為什么呢?
NSOperation本身并不提供多線程的能力,任務是在當前線程中異步執行,任務執行完成后才執行后面的代碼。cancel方法寫在當前線程,而當前線程一直卡在while循環里,所以cancel方法根本就不會被調用。
 
既然在同一線程中不能取消死循環的任務,那么,將任務放到后臺,在主線程中取消呢?NSOperationQueue提供多線程的能力,將NSOperation任務放到queue中執行。看下面代碼:
- (void)startOperation
{
    NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
        while (1) {
            NSLog(@"Test operation cancel funcation");
        }
    }];

    self.operation = operation;

    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    [queue addOperation:operation];
//    [operation cancel]; 
   
    [self performSelector:@selector(cancelOperation) withObject:nil afterDelay:0.01f];
}
 
這里的cancelOperation方法和上面一樣省略了,operation任務被添加到NSOperationQueue中在下一個Runloop會被執行,如果緊跟添加后取消,任務就不會被執行。所以我們放到延遲方法中取消operation。這樣總能退出while循環了吧!測試發現while循環依然在執行,這又是什么原因了?
 
在蘋果官方文檔上講解NSOperation有這么一段話:
 If an operation were terminated outright, there might not be a way to reclaim resources that had been allocated. As a result, operation objects are expected to check for cancellation events and to exit gracefully when they occur in the middle of the operation.
大致意思是任務被中斷了,但分配的內存資源有可能回收不了,所以在執行任務前要檢查任務是否被取消了。還有保證任務被取消后釋放分配的內存,這點在后面的實現NSOperation子類中要特別注意。
 
下面這樣才是正確的
- (void)startOperation
{
    __weak ViewController *wself = self;
   
    NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
        while (wself.operation.isCancelled == NO) {
            NSLog(@"Test operation cancel funcation");
        }
    }];

    self.operation = operation;

    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    [queue addOperation:operation];
 
    [self performSelector:@selector(cancelOperation) withObject:nil afterDelay:0.01f];
}
 
上面使用的都是系統提供的NSOperation的子類,我們也可以自己定義新的子類。NSOperation的任務默認是非并發執行的,只讀屬性BOOL concurrent(iOS7之后使用BOOL asynchronous)默認返回NO。
 
 
將NSOperationQueue之前先弄明白幾個概念:線程、同步、異步、并發
線程是程序執行的最小單元,是進程中的一個實體,是被系統獨立調度和分派的基本單位,同一進程中的多個線程可以并發執行。
線程同步是多個線程發生競爭資源,需要依次訪問,線程異步是多個線程可以同時對同一資源進行訪問
執行同步是等待任務完成才能執行后面的代碼,執行異步是異步調用發出后,接著執行后面的代碼,實際執行調用的過程在后面完成,像performSelector調用。
并發執行是指不需要等待任務執行完也能執行后面的代碼。
 
上面我用到了NSOperationQueue,處于cocoa最上層處理多線程隊列。NSOperationQueue會給加入的每個NSOperation任務開啟一個新的線程,當任務執行完成后銷毀其線程。多個任務是異步執行的,既為異步隊列。但可以設置NSOperationQueue的最大同時執行的任務數為1(maxConcurrentOperationCount = 1)來實現同步隊列。非并發的任務添加到NSOperationQueue隊列中也實現了異步執行。因此如果你需要將NSOperation任務添加到NSOperationQueue隊列中,那就不需要實現NSOperation的并發任務。
 
關于自定義NSOperation子類和實現concurrent任務會在下一節講。
 

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 欧洲精品色| 在线成人精品视频 | 72pao成人国产永久免费视频 | 国产成人精品免费视频大全最热 | 日本aaaa片毛片免费观看视频 | 九一国产精品 | 欧美成人a | 久久国产免费视频 | 免费播放欧美毛片 | 亚洲精品aⅴ中文字幕乱码 欧美囗交 | 日本一区二区不卡高清 | 久久国产精品电影 | 日韩毛片网 | 久久伊人精品视频 | 91成人久久| 91女上位 在线播放 性欧美日本 | 久久久久亚洲精品国产 | 国产无遮挡一区二区三区毛片日本 | 欧美黄色免费视频 | 免费黄色欧美视频 | 精品视频在线免费看 | 一边吃奶一边摸下娇喘 | 中文字幕综合在线观看 | 日韩一级视频 | 91成人精品| 日本免费aaa观看 | 成年人激情在线 | 爽毛片| 欧美精品电影一区二区 | 国产精品久久久久久久久岛 | 欧美成人综合视频 | 日本68xxxx | 中国杭州少妇xxxx做受 | 久久欧美亚洲另类专区91大神 | 日本成人一二三区 | 免看黄大片aa | 欧美成人精品欧美一级乱黄 | 欧美精品一区二区三区久久久 | 中文字幕在线成人 | 日韩av影片在线观看 | 国产精品资源手机在线播放 |