IOS学习之路七(使用 Operation 异步运行任务)
在 application delegate 頭文件(.h)中聲明一個 operation 隊(duì)列和兩個 invocation operations:?
#import <UIKit/UIKit.h> @interface Running_Tasks_Asynchronously_with_OperationsAppDelegate : UIResponder <UIApplicationDelegate> @property (nonatomic, strong) UIWindow *window; @property (nonatomic, strong) NSOperationQueue *operationQueue; @property (nonatomic, strong) NSInvocationOperation *firstOperation; @property (nonatomic, strong) NSInvocationOperation *secondOperation; @endapplication delegate 的實(shí)現(xiàn)文件(.m 文件)如下:?
#import "Running_Tasks_Asynchronously_with_OperationsAppDelegate.h" @implementation Running_Tasks_Asynchronously_with_OperationsAppDelegate @synthesize window = _window; @synthesize firstOperation; @synthesize secondOperation; @synthesize operationQueue; - (void) firstOperationEntry:(id)paramObject{ NSLog(@"%s", __FUNCTION__); NSLog(@"Parameter Object = %@", paramObject); NSLog(@"Main Thread = %@", [NSThread mainThread]); NSLog(@"Current Thread = %@", [NSThread currentThread]); } - (void) secondOperationEntry:(id)paramObject{ NSLog(@"%s", __FUNCTION__); NSLog(@"Parameter Object = %@", paramObject); NSLog(@"Main Thread = %@", [NSThread mainThread]); NSLog(@"Current Thread = %@", [NSThread currentThread]); } - (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ NSNumber *firstNumber = [NSNumber numberWithInteger:111]; NSNumber *secondNumber = [NSNumber numberWithInteger:222]; self.firstOperation =[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(firstOperationEntry:) object:firstNumber]; self.secondOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(secondOperationEntry:) object:secondNumber]; self.operationQueue = [[NSOperationQueue alloc] init]; /* Add the operations to the queue */  [self.operationQueue addOperation:self.firstOperation]; [self.operationQueue addOperation:self.secondOperation]; NSLog(@"Main thread is here"); self.window = [[UIWindow alloc] initWithFrame: [[UIScreen mainScreen] bounds]]; self.window.backgroundColor = [UIColor whiteColor]; [self.window makeKeyAndVisible]; return YES; } @end在實(shí)現(xiàn)的代碼里面都發(fā)生了什么呢:
?有兩個方法:firstOperationEntry:和 secondOperationEntry:,每個方法都接收一個對象?
作為參數(shù),并且在控制臺窗口打印出當(dāng)前線程、主線程和參數(shù)。這兩個入口函數(shù)的
invocation operation 將被添加到一個 operation 隊(duì)列中。
?我們初始化兩個 NSInvocationOperation 類型對象,并給每個 operation 設(shè)置目標(biāo)
selector 入口點(diǎn),如之前所述。
?然后我們初始化一個 NSOperationQueue 類型對象。(當(dāng)然也可以在入口方法前面創(chuàng)
建)隊(duì)列對象將負(fù)責(zé)管理 operation 對象的并發(fā)。
? 我們調(diào)用 NSOperationQueue 的實(shí)例方法 addOperation:把每個 invocation operation 添加
到 operation 隊(duì)列中。在這里,operation 隊(duì)列可能會也可能不會立即通過 nvocationoperation 的 start 方法啟動 invocation operation。但是,需要牢記重要的一點(diǎn):添加operations 至 operation 隊(duì)列后,你不能手動啟動 operations,必須交由 operation 隊(duì)列負(fù)責(zé)。
現(xiàn)在,我們運(yùn)行一次示例代碼,在控制臺窗口可以看到如下結(jié)果:[Running_Tasks_Asynchronously_with_OperationsAppDelegate firstOperationEntry:]Main thread is here
Parameter Object = 111
[Running_Tasks_Asynchronously_with_OperationsAppDelegate secondOperationEntry:]Main Thread = <NSThread: 0x6810260>{name = (null), num = 1}
Parameter Object = 222
Current Thread = <NSThread: 0x6805c20>{name = (null), num = 3}Main Thread = <NSThread: 0x6810260>{name = (null), num = 1}Current Thread = <NSThread: 0x6b2d1d0>{name = (null), num = 4}?
如果我們子類化了一個 NSOperation 類,并且把這個子類的實(shí)例對象添加到了 operation隊(duì)列,我們需要做稍微的改動。記住以下幾點(diǎn):
? 由于當(dāng)把 NSOperation 的子類對象添加到一個 operation 隊(duì)列中,該對象會異步運(yùn)行。由此,你必須 overrideNSOperation 的實(shí)例方法 isConcurrent,在該方法中返回 YES。? 在 start 方法里面執(zhí)行 main 任務(wù)之前,需要定期的調(diào)用 isCancelled 方法來檢測該函數(shù)的返回值,以確定是退出 start 方法還是開始運(yùn)行 operation。在這里,當(dāng) operation 添加到隊(duì)列中后,operation 的 start 方法將會被 operation 隊(duì)列調(diào)用,start 方法中,調(diào)用isCanelled 方法確定 operation 是否被取消。如果 operation 被取消了,只需要從 start?
方法中簡單的返回即可。如果沒被取消,會在 start 方法中調(diào)用 main 方法。
? 在 main task 實(shí)現(xiàn)部分中 override main 函數(shù),main 函數(shù)將被 operation 執(zhí)行。在這個函數(shù)里面確保分配和初始化 autorelease pool,并且在返回之前釋放這個 pool。
? 重載 operation 的 isFinished 和 isExecuting 方法,這兩個函數(shù)返回對應(yīng)的 BOOL 值,代表 operation 是執(zhí)行完畢還是在執(zhí)行中。
下面是我們的 operation 聲明(.h 文件):?
#import <Foundation/Foundation.h> @interface SimpleOperation : NSOperation /* Designated Initializer */ - (id) initWithObject:(NSObject *)paramObject; @end The implementation of the operation is as follows: #import "SimpleOperation.h" @implementation SimpleOperation NSObject *givenObject; BOOL finished; BOOL executing; - (id) init { NSNumber *dummyObject = [NSNumber numberWithInteger:123]; return([self initWithObject:dummyObject]); } - (id) initWithObject:(NSObject *)paramObject{ self = [super init]; if (self != nil){ /* Keep these values for the main method */ givenObject = paramObject; } return(self); } - (void) start { /* If we are cancelled before starting, then we have to return immediately and generate the required KVO notifications */ if ([self isCancelled]){ /* If this operation *is* cancelled */ /* KVO compliance */ [self willChangeValueForKey:@"isFinished"]; finished = YES; [self didChangeValueForKey:@"isFinished"]; return;  } else { /* If this operation is *not* cancelled */ /* KVO compliance */ [self willChangeValueForKey:@"isExecuting"]; executing = YES; /* Call the main method from inside the start method */ [self main]; [self didChangeValueForKey:@"isExecuting"]; } } - (void) main { @try { @autoreleasepool { /* Keep a local variable here that must get set to YES whenever we are done with the task */BOOL taskIsFinished = NO; /* Create a while loop here that only exists if the taskIsFinished variable is set to YES or the operation has been cancelled */ while (taskIsFinished == NO && [self isCancelled] == NO){ /* Perform the task here */ NSLog(@"%s", __FUNCTION__); NSLog(@"Parameter Object = %@", givenObject); NSLog(@"Main Thread = %@", [NSThread mainThread]); NSLog(@"Current Thread = %@", [NSThread currentThread]); /* Very important. This way we can get out of the loop and we are still complying with the cancellation rules of operations */ taskIsFinished = YES; } /* KVO compliance. Generate the required KVO notifications */ [self willChangeValueForKey:@"isFinished"]; [self willChangeValueForKey:@"isExecuting"]; finished = YES; executing = NO; [self didChangeValueForKey:@"isFinished"]; [self didChangeValueForKey:@"isExecuting"]; } } @catch (NSException * e) { NSLog(@"Exception %@", e); } } - (BOOL) isConcurrent{ return YES; } - (BOOL) isFinished{ /* Simply return the value */ return finished; } - (BOOL) isExecuting{ /* Simply return the value */ return executing; } @end現(xiàn)在可以在其他任何類中使用上面定義的這個 operation 類了,比如在 applicationdelegate 中。下面是 application delegate 的聲明,使用了新的 operation 類,并將其添加到了新的 operation 隊(duì)列中:?
#import <UIKit/UIKit.h> @class SimpleOperation; @interface Running_Tasks_Asynchronously_with_OperationsAppDelegate : UIResponder <UIApplicationDelegate> @property (nonatomic, strong) UIWindow *window; @property (nonatomic, strong) NSOperationQueue *operationQueue; @property (nonatomic, strong) SimpleOperation *firstOperation; @property (nonatomic, strong) SimpleOperation *secondOperation; @endapplication delegate 的實(shí)現(xiàn)部分如下:?
#import "Running_Tasks_Asynchronously_with_OperationsAppDelegate.h" #import "SimpleOperation.h" @implementation Running_Tasks_Asynchronously_with_OperationsAppDelegate @synthesize window = _window; @synthesize firstOperation; @synthesize secondOperation; @synthesize operationQueue; - (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ NSNumber *firstNumber = [NSNumber numberWithInteger:111]; NSNumber *secondNumber = [NSNumber numberWithInteger:222]; self.firstOperation = [[SimpleOperation alloc] initWithObject:firstNumber]; self.secondOperation = [[SimpleOperation alloc] initWithObject:secondNumber]; self.operationQueue = [[NSOperationQueue alloc] init]; /* Add the operations to the queue */ [self.operationQueue addOperation:self.firstOperation]; [self.operationQueue addOperation:self.secondOperation]; NSLog(@"Main thread is here"); self.window = [[UIWindow alloc] initWithFrame: [[UIScreen mainScreen] bounds]]; self.window.backgroundColor = [UIColor whiteColor]; [self.window makeKeyAndVisible]; return YES; } @end打印到控制臺窗口的結(jié)果與之前使用并發(fā) invocation operation 類似:?
Main thread is here
-[SimpleOperation main]
-[SimpleOperation main]
Parameter Object = 222
Parameter Object = 222
Main Thread = <NSThread: 0x6810260>{name = (null), num = 1}Main Thread = <NSThread: 0x6810260>{name = (null), num = 1}Current Thread = <NSThread: 0x6a10b90>{name = (null), num = 3}Current Thread = <NSThread: 0x6a13f50>{name = (null), num = 4}?
轉(zhuǎn)載于:https://www.cnblogs.com/lixingle/p/3312965.html
總結(jié)
以上是生活随笔為你收集整理的IOS学习之路七(使用 Operation 异步运行任务)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: IOS 图片上传处理 图片压缩 图片处理
- 下一篇: flash、div、iframe的层级