+++
Categories = ["iOS",]
Tags = ["iOS","NSOperation"]
date = "2014-11-17T14:01:09+08:00"
title = "多線程 NSOperation"
+++
NSOperation介紹
NSOperation是一個(gè)抽象的基類,表示一個(gè)獨(dú)立的計(jì)算單元,可以為子類提供有用且線程安全的建立狀態(tài),優(yōu)先級(jí),依賴和取消等操作。系統(tǒng)已經(jīng)給我們封裝了NSBlockOperation和NSInvocationOperation這兩個(gè)實(shí)體類。
- 使用NSOperation處理多線程時(shí),就是將“操作”添加到隊(duì)列中。
- NSOperation是一個(gè)抽象類,不能直接使用(方法沒(méi)有實(shí)現(xiàn)),約束子類都具有共同的屬性和方法。
- NSOperation的子類:NSInvocationOperation、NSBlockOperation、自定義NSOperation。
- 通過(guò)NSOperationQueue可以創(chuàng)建并發(fā)隊(duì)列,獲取主隊(duì)列,獲取當(dāng)前隊(duì)列。
NSOperation定義
- (void)start;
- (void)main;
@property (readonly, getter=isCancelled) BOOL cancelled;
- (void)cancel;
@property (readonly, getter=isExecuting) BOOL executing;
@property (readonly, getter=isFinished) BOOL finished;
@property (readonly, getter=isConcurrent) BOOL concurrent; // To be deprecated; use and override 'asynchronous' below
@property (readonly, getter=isAsynchronous) BOOL asynchronous NS_AVAILABLE(10_8, 7_0);
@property (readonly, getter=isReady) BOOL ready;
- (void)addDependency:(NSOperation *)op;
- (void)removeDependency:(NSOperation *)op;
@property (readonly, copy) NSArray *dependencies;
typedef NS_ENUM(NSInteger, NSOperationQueuePriority) {
NSOperationQueuePriorityVeryLow = -8L,
NSOperationQueuePriorityLow = -4L,
NSOperationQueuePriorityNormal = 0,
NSOperationQueuePriorityHigh = 4,
NSOperationQueuePriorityVeryHigh = 8
};
@property NSOperationQueuePriority queuePriority;
@property (copy) void (^completionBlock)(void) NS_AVAILABLE(10_6, 4_0);
- (void)waitUntilFinished NS_AVAILABLE(10_6, 4_0);
@property double threadPriority NS_DEPRECATED(10_6, 10_10, 4_0, 8_0);
@property NSQualityOfService qualityOfService NS_AVAILABLE(10_10, 8_0);
@property (copy) NSString *name NS_AVAILABLE(10_10, 8_0);
狀態(tài)
NSOperation提供了ready cancelled executing finished這幾個(gè)狀態(tài)變化,我們的開(kāi)發(fā)也是必須處理自己關(guān)心的其中的狀態(tài)。這些狀態(tài)都是基于keypath的KVO通知決定,所以在你手動(dòng)改變自己關(guān)心的狀態(tài)時(shí),請(qǐng)別忘了手動(dòng)發(fā)送通知。這里面每個(gè)屬性都是相互獨(dú)立的,同時(shí)只可能有一個(gè)狀態(tài)是YES。finished這個(gè)狀態(tài)在操作完成后請(qǐng)及時(shí)設(shè)置為YES,因?yàn)镹SOperationQueue所管理的隊(duì)列中,只有isFinished為YES時(shí)才將其移除隊(duì)列,這點(diǎn)在內(nèi)存管理和避免死鎖很關(guān)鍵。
依賴
NSOperation中我們可以為操作分解為若干個(gè)小的任務(wù),通過(guò)添加他們之間的依賴關(guān)系進(jìn)行操作,我們可以直接調(diào)用 - (void)addDependency:(NSOperation*)op; 這個(gè)方法添加依賴.依賴關(guān)系可以跨操作隊(duì)列,操作不再同一個(gè)隊(duì)列中,依賴關(guān)系也是存在的。
執(zhí)行
執(zhí)行一個(gè)operation有兩種方法,第一種是自己手動(dòng)的調(diào)用start這個(gè)方法,這種方法調(diào)用會(huì)在當(dāng)前調(diào)用的線程進(jìn)行同步執(zhí)行,所以在主線程里面自己一定要小心的調(diào)用,不然就會(huì)把主線程給卡死。第二種是將operation添加到operationQueue中去,這個(gè)也是我們用得最多的也是提倡的方法。NSOperationQueue會(huì)在我們添加進(jìn)去operation的時(shí)候盡快進(jìn)行執(zhí)行。當(dāng)然如果 NSOperationQueue的maxConcurrentOperationCount 如果設(shè)置為1的話,進(jìn)相當(dāng)于FIFO了。
GCD和NSOperation的對(duì)比
- GCD
GCD是iOS4.0推出的,主要針對(duì)多核CPU做了優(yōu)化,是C語(yǔ)言的技術(shù)。
GCD是將任務(wù)(block)添加到隊(duì)列(串行/并行/全局/主隊(duì)列),并且以同步/異步的方式執(zhí)行任務(wù)的函數(shù)。
GCD提供給了一些NSOperation不具備的功能:①一次性執(zhí)行;②延遲執(zhí)行;③調(diào)度組。
- NSOperation
NSOperation是iOS2.0推出的,iOS4.0之后重寫(xiě)了NSOperation。
NSOperation將操作(異步的任務(wù))添加到隊(duì)列(并發(fā)隊(duì)列),就會(huì)執(zhí)行指定操作的函數(shù)。
NSOperation里提供的方便的操作:①最大并發(fā)數(shù);②隊(duì)列的暫停/繼續(xù);③取消所有的操作;④指定操作之間的依賴關(guān)系(GCD可以用同步實(shí)現(xiàn))。