ios 任務、線程、定時器


一:operations(任務)

 

cocoa提供了三種不同的operations

 

1:Block operations(NSBlockOperation
These facilitate the execution of one or more block objects.

 

 

C代碼    收藏代碼
  1. #import <UIKit/UIKit.h>  
  2. @inter<span>f</span>ace OperationsAppDelegate : NSObject <UIApplicationDelegate> {  
  3.     UIWindow *window;  
  4.     NSBlockOperation *simpleOperation;  
  5. }  
  6.   
  7. @property (nonatomic, retain) IBOutlet UIWindow *window;  
  8. @property (nonatomic, retain) NSBlockOperation *simpleOperation;  
  9.   
  10. @end  

 

C代碼    收藏代碼
  1. #import "OperationsAppDelegate.h"  
  2.   
  3. @implementation OperationsAppDelegate  
  4. @synthesize window;  
  5. @synthesize simpleOperation;  
  6.   
  7. - (BOOL) application:(UIApplication *)application did<span>F</span>inishLaunchingWithOptions:(NSDictionary *)launchOptions {  
  8.     /* Here is our block */  
  9.     NSBlockOperation *newBlockOperation = [NSBlockOperation blockOperationWithBlock:^{  
  10.                             NSLog(@"Main Thread = %@", [NSThread mainThread]);  
  11.                             NSLog(@"Current Thread = %@", [NSThread currentThread]);  
  12.                             NSUInteger counter = 0;  
  13.                             <span>f</span>or (counter = 0;counter < 1000;counter++){  
  14.                                 NSLog(@"Count = %lu", (unsigned long)counter);  
  15.                             }  
  16.                                 }];  
  17.   
  18.     /* Make sure we keep the re<span>f</span>erence somewhere */  
  19.     sel<span>f</span>.simpleOperation = newBlockOperation;  
  20.       
  21.     /* Start the operation */  
  22.     [sel<span>f</span>.simpleOperation start];  
  23.   
  24.     /* Print something out just to test i<span>f</span> we have to wait 
  25.     <span>f</span>or the block to execute its code or not */  
  26.       
  27.     NSLog(@"Main thread is here");  
  28.     [window makeKeyAndVisible];  
  29.     return YES;  
  30. }  
  31.   
  32.   
  33. - (void)dealloc {  
  34.     [simpleOperation release];  
  35.     [window release];  
  36.     [super dealloc];  
  37. }  
  38.   
  39. @end  

 

 


2:Invocation operations(NSInvocationOperation
These allow you to invoke a method in another, currently existing object.

 

NSNumber *simpleObject = [NSNumber numberWithInteger:123];

NSInvocationOperation *newOperation = [[NSInvocationOperation alloc] initWithTarget:selfselector:@selector(simpleOperationEntry:) object:simpleObject];

[newOperation  start];

 

 

調用start方法執行改任務

 

C代碼    收藏代碼
  1. #import <UIKit/UIKit.h>  
  2. @inter<span>f</span>ace OperationsAppDelegate : NSObject <UIApplicationDelegate> {  
  3.     UIWindow *window;  
  4.     NSInvocationOperation *simpleOperation;  
  5. }  
  6.   
  7. @property (nonatomic, retain) IBOutlet UIWindow *window;  
  8. @property (nonatomic, retain) NSInvocationOperation *simpleOperation;  
  9.   
  10. @end  

 

C代碼    收藏代碼
  1. - (void) simpleOperationEntry:(id)paramObject{  
  2.   
  3.     NSLog(@"Parameter Object = %@", paramObject);  
  4.     NSLog(@"Main Thread = %@", [NSThread mainThread]);  
  5.     NSLog(@"Current Thread = %@", [NSThread currentThread]);  
  6. }  
  7.   
  8. - (BOOL) application:(UIApplication *)application did<span>F</span>inishLaunchingWithOptions:(NSDictionary *)launchOptions {  
  9.   
  10.     NSNumber *simpleObject = [NSNumber numberWithInteger:123];  
  11.     NSInvocationOperation *newOperation =[[NSInvocationOperation alloc] initWithTarget:sel<span>f</span> selector:@selector(simpleOperationEntry:) object:simpleObject];  
  12.     sel<span>f</span>.simpleOperation = newOperation;  
  13.     [newOperation release];  
  14.   
  15.     [sel<span>f</span>.simpleOperation start];  
  16.     [window makeKeyAndVisible];  
  17.     return YES;  
  18. }  
  19.   
  20. - (void)dealloc {  
  21.   
  22.     [simpleOperation release];  
  23.     [window release];  
  24.     [super dealloc];  
  25. }  

 

 

 

 

 

 


3:Plain operations(簡單的任務)NSOperation的子類


These are plain operation classes that need to be subclassed. The code to be executed
will be written inside the main method of the operation object.

 

 

C代碼    收藏代碼
  1. @inter<span>f</span>ace MyTask : NSOperation {   
  2.     int operationId;   
  3. }  
  4.   
  5. @property int operationId;  
  6.   
  7. @end  

 

這里的operationId屬性不是必須的

 

C代碼    收藏代碼
  1. @implementation MyTask  
  2.   
  3. @synthesize operationId;  
  4.   
  5. - (void)main{   
  6.     NSLog(@"task %i run … ",operationId);   
  7.     [NSThread sleep<span>F</span>orTimeInterval:10];   
  8.     NSLog(@"task %i is <span>f</span>inished. ",operationId);   
  9. }  
  10.   
  11. @end  

 

 

必須
- (void)main;方法,[MyTask start]是執行main方法

 

 

二:任務隊列(NSOperationQueue)

 

NSOperationQueue *newOperationQueue = [[NSOperationQueue alloc] init];
[ newOperationQueue  addOperation:Operation];

 

 

以上三種Operation都可以添加到NSOperationQueue中,添加后立即被執行。

 

NSOperationQueue 可以設置最大並行執行任務數。默認值為-1無限制。

 

 

三:多個任務之間存在依賴關系

 

設置方式:

[self.firstOperation addDependency:self.secondOperation];

 

dependency:附屬的意思

 

把secondOperation做為firstOperation的附屬。因此先執行secondOperation,再執行firstOperation 。

 

 

四:延時執行某個方法

 

1:performSelector:withObject:afterDelay:

 

 

C代碼    收藏代碼
  1. - (void) connectionHasFailedWithError:(NSError *)paramError onRemoteURL:(NSURL *)paramRemoteURL{  
  2.     /* We failed to download the file. Attempt to download it again after 3 seconds */  
  3.     [self performSelector:@selector(attemptToDownloadRemoteURL:) withObject:paramRemoteURL afterDelay:3.0f];  
  4. }  
  5.   
  6. - (void) attemptToDownloadRemoteURL:(NSURL *)paramRemoteURL{  
  7.     /* Attempt to download the remote file again here by initializing 
  8.     a new connection ... */  
  9. }  

 

該方法只能接受一個參數。如果需要傳遞多個參數怎么辦呢???

     讓selector調用的方法接受的參數類型修改為Dictionary類型。

 

 

(1)如果調用的selector不接受參數則,withObject:nil

(2) 通過performSelector:withObjcet:afterDelay調用的方法不能有返回值

 

 

2:取消延時執行的方法

 

(1)cancelPreviousPerformRequestsWithTarget: 

(2) cancelPreviousPerformRequestsWithTarget:selector:object:

 

 

五:NSTimer

 

1:scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:

 

2:invalidate

調用invalidate方法,不僅是釋放NSTimer,還釋放userinfo對象。
如果repeats設置為NO,NSTimer在調用完成之后就知道失效,隨即釋放userinfo對象

 

3:scheduledTimerWithTimeInterval:invocation:repeats:

 

C代碼    收藏代碼
  1. - (void) startPainting{  
  2.     SEL selectorToCall = @selector(paint:);  
  3.     NSMethodSignature *methodSignature = [[self class] instanceMethodSignatureForSelector:selectorToCall];  
  4.     NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature];  
  5.     [invocation setTarget:self];  
  6.     [invocation setSelector:selectorToCall];  
  7.   
  8. /* Start a scheduled timer now */  
  9. NSTimer *newTimer =[NSTimer scheduledTimerWithTimeInterval:1.0  
  10.                         invocation:invocation  
  11.                            repeats:YES];  
  12.   
  13.     self.paintingTimer = newTimer;  
  14. }  

 

 4:timerWithTimeInterval:target:selector:userInfo:repeats:

   (用該方式,需要把timer添加到runloop中)

 

C代碼    收藏代碼
  1. - (void) startPainting{  
  2.     NSTimer *newTimer = [NSTimer timerWithTimeInterval:1.0  
  3.                             target:self  
  4.                           selector:@selector(paint:)  
  5.                           userInfo:nil  
  6.                            repeats:YES];  
  7.   
  8.     self.paintingTimer = newTimer;  
  9.   
  10.     [[NSRunLoop currentRunLoop] addTimer:self.paintingTimer forMode:NSDefaultRunLoopMode];  
  11. }  

 

5:timerWithTimeInterval:invocation:repeats:

  (用該方式,需要把timer添加到runloop中)

C代碼    收藏代碼
  1. - (void) startPainting{   
  2.     SEL selectorToCall = @selector(paint:);  
  3.     NSMethodSignature *methodSignature =[[self class] instanceMethodSignatureForSelector:selectorToCall];  
  4.     NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature];  
  5.   
  6.     [invocation setTarget:self];  
  7.     [invocation setSelector:selectorToCall];  
  8.     NSTimer *newTimer = [NSTimer timerWithTimeInterval:1.0  
  9.                         invocation:invocation  
  10.                            repeats:YES];  
  11.     self.paintingTimer = newTimer;  
  12.     [[NSRunLoop currentRunLoop] addTimer:self.paintingTimer  
  13.                      forMode:NSDefaultRunLoopMode];  
  14. }  

 

 

6:NSTimer 響應函數定義格式

 

並需有一個NSTimer *類型的參數

 

C代碼    收藏代碼
  1. - (void) paint:(NSTimer *)paramTimer{  
  2.     /* Do something here */  
  3.     NSLog(@"Painting");  
  4. }  

 

 

 

六:NSThread

 

1:initWithTarget:selector:object:

 

2:detachNewThreadSelector:toTarget: withObject:

 

以上兩種方式,selector調用的函數,必須聲明自己的NSAutoreleasePool

 

 

3:performSelectorInBackground: withObject:

     一個簡單的方法來創建線程,而無需直接處理線程。

C代碼    收藏代碼
  1. [self performSelectorInBackground:@selector(thirdCounter) withObject:nil];  

 

4:start

調用start方法啟動線程

 

5:cancel

調用cancel方法,並把變量賦值為nil

 

6:cancel vs exit

 

對於線程調用cancel方法停止,不要調用exit,因為exit方法沒有給線程清理自己並釋放資源的時間

 

7:線程的內存泄露

 

C代碼    收藏代碼
  1.  - (void) newThreadEntryPoint{  
  2.     /* A thread without an autorelease pool to test the following code */  
  3.     //NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];  
  4.       
  5.     /* This WILL cause a memory leak */  
  6.     [self performSelector:@selector(allocateSomething)];  
  7.   
  8.     /* This will NOT cause a memory leak */  
  9.     [self performSelectorOnMainThread:@selector(allocateSomething)  
  10.                 withObject:nil  
  11.                  waitUntilDone:YES];  
  12.     //[pool release];  
  13. }  
  14.   
  15. - (void) allocateSomething{  
  16.     NSBundle *mainBundle = [NSBundle mainBundle];  
  17.     NSString *imagePath = [mainBundle pathForResource:@"MyImage" ofType:@"png"];  
  18.     NSData *imageData = [NSData dataWithContentsOfFile:imagePath];  
  19.     UIImage *myImage = [[[UIImage alloc] initWithData:imageData] autorelease];  
  20.     /* Do something with the image here */  
  21. }  
  22.   
  23. - (void)viewDidLoad {  
  24.   
  25.     [NSThread detachNewThreadSelector:@selector(newThreadEntryPoint)  
  26.                  toTarget:self  
  27.                    withObject:nil];  
  28. }  

 

 

UIImage *myImage = [[[UIImage alloc] initWithData:imageData] autorelease];-------------自動釋放池的范圍

 

/* This WILL cause a memory leak */
[self performSelector:@selector(allocateSomething)];

調用改方法myImage 對象被添加進該新建線程的自動釋放池,但因為在這里沒有聲明NSAutoreleasePool 造成內存泄露

 


 /* This will NOT cause a memory leak */
[self performSelectorOnMainThread:@selector(allocateSomething)
withObject:nil
     waitUntilDone:YES];

 

調用改方法myImage 對象被放進主線程的自動釋放池,在主線程銷毀是被自動釋放

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM