ios 线程、定时器

时间:2022-01-12 23:31:12

一:延时执行某个方法

 

1:performSelector:withObject:afterDelay:

 

 

C代码   ios 线程、定时器
  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代码   ios 线程、定时器
  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代码   ios 线程、定时器
  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代码   ios 线程、定时器
  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代码   ios 线程、定时器
  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代码   ios 线程、定时器
  1. [self performSelectorInBackground:@selector(thirdCounter) withObject:nil];  

 

4:start

调用start方法启动线程

 

5:cancel

调用cancel方法,并把变量赋值为nil

 

6:cancel vs exit

 

对于线程调用cancel方法停止,不要调用exit,因为exit方法没有给线程清理自己并释放资源的时间

 

7:线程的内存泄露

 

C代码   ios 线程、定时器
  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 对象被放进主线程的自动释放池,在主线程销毁是被自动释放