`
janedoneway
  • 浏览: 582102 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

ios 任务、线程、定时器

 
阅读更多

From : http://o0o0o0o.iteye.com/blog/1326772

一:operations(任务)

 

cocoa提供了三种不同的operations

 

1:Block operations(NSBlockOperation
These f acilitate 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.                             for (counter = 0;counter < 1000;counter++){  
  14.                                 NSLog(@"Count = %lu" , (unsigned  long )counter);  
  15.                             }  
  16.                                 }];  
  17.   
  18.     /* Make sure we keep the reference somewhere */   
  19.     self.simpleOperation = newBlockOperation;  
  20.       
  21.     /* Start the operation */   
  22.     [self.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:self selector:@selector(simpleOperationEntry:) object:simpleObject];

[newOperation  start];

 

 

调用start方法执行改任务

 

C代码  收藏代码
  1. #import <UIKit/UIKit.h>   
  2. @interface 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 didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {  
  9.   
  10.     NSNumber *simpleObject = [NSNumber numberWithInteger:123];  
  11.     NSInvocationOperation *newOperation =[[NSInvocationOperation alloc] initWithTarget:self    selector:@selector(simpleOperationEntry:) object:simpleObject];  
  12.     self.simpleOperation = newOperation;  
  13.     [newOperation release];  
  14.   
  15.     [self.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. @interface 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 对象被放进主线程的自动释放池,在主线程销毁是被自动释放

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics