一:延时执行某个方法
1:performSelector:withObject:afterDelay:
- - (void) connectionHasFailedWithError:(NSError *)paramError onRemoteURL:(NSURL *)paramRemoteURL{
- /* We failed to download the file. Attempt to download it again after 3 seconds */
- [self performSelector:@selector(attemptToDownloadRemoteURL:) withObject:paramRemoteURL afterDelay:3.0f];
- }
- - (void) attemptToDownloadRemoteURL:(NSURL *)paramRemoteURL{
- /* Attempt to download the remote file again here by initializing
- a new connection ... */
- }
该方法只能接受一个参数。如果需要传递多个参数怎么办呢???
让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:
- - (void) startPainting{
- SEL selectorToCall = @selector(paint:);
- NSMethodSignature *methodSignature = [[self class] instanceMethodSignatureForSelector:selectorToCall];
- NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature];
- [invocation setTarget:self];
- [invocation setSelector:selectorToCall];
- /* Start a scheduled timer now */
- NSTimer *newTimer =[NSTimer scheduledTimerWithTimeInterval:1.0
- invocation:invocation
- repeats:YES];
- self.paintingTimer = newTimer;
- }
4:timerWithTimeInterval:target:selector:userInfo:repeats:
(用该方式,需要把timer添加到runloop中)
- - (void) startPainting{
- NSTimer *newTimer = [NSTimer timerWithTimeInterval:1.0
- target:self
- selector:@selector(paint:)
- userInfo:nil
- repeats:YES];
- self.paintingTimer = newTimer;
- [[NSRunLoop currentRunLoop] addTimer:self.paintingTimer forMode:NSDefaultRunLoopMode];
- }
5:timerWithTimeInterval:invocation:repeats:
(用该方式,需要把timer添加到runloop中)
- - (void) startPainting{
- SEL selectorToCall = @selector(paint:);
- NSMethodSignature *methodSignature =[[self class] instanceMethodSignatureForSelector:selectorToCall];
- NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature];
- [invocation setTarget:self];
- [invocation setSelector:selectorToCall];
- NSTimer *newTimer = [NSTimer timerWithTimeInterval:1.0
- invocation:invocation
- repeats:YES];
- self.paintingTimer = newTimer;
- [[NSRunLoop currentRunLoop] addTimer:self.paintingTimer
- forMode:NSDefaultRunLoopMode];
- }
6:NSTimer 响应函数定义格式
并需有一个NSTimer *类型的参数
- - (void) paint:(NSTimer *)paramTimer{
- /* Do something here */
- NSLog(@"Painting");
- }
三:NSThread
1:initWithTarget:selector:object:
2:detachNewThreadSelector:toTarget: withObject:
以上两种方式,selector调用的函数,必须声明自己的NSAutoreleasePool
3:performSelectorInBackground: withObject:
一个简单的方法来创建线程,而无需直接处理线程。
- [self performSelectorInBackground:@selector(thirdCounter) withObject:nil];
4:start
调用start方法启动线程
5:cancel
调用cancel方法,并把变量赋值为nil
6:cancel vs exit
对于线程调用cancel方法停止,不要调用exit,因为exit方法没有给线程清理自己并释放资源的时间
7:线程的内存泄露
- - (void) newThreadEntryPoint{
- /* A thread without an autorelease pool to test the following code */
- //NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- /* This WILL cause a memory leak */
- [self performSelector:@selector(allocateSomething)];
- /* This will NOT cause a memory leak */
- [self performSelectorOnMainThread:@selector(allocateSomething)
- withObject:nil
- waitUntilDone:YES];
- //[pool release];
- }
- - (void) allocateSomething{
- NSBundle *mainBundle = [NSBundle mainBundle];
- NSString *imagePath = [mainBundle pathForResource:@"MyImage" ofType:@"png"];
- NSData *imageData = [NSData dataWithContentsOfFile:imagePath];
- UIImage *myImage = [[[UIImage alloc] initWithData:imageData] autorelease];
- /* Do something with the image here */
- }
- - (void)viewDidLoad {
- [NSThread detachNewThreadSelector:@selector(newThreadEntryPoint)
- toTarget:self
- withObject:nil];
- }
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 对象被放进主线程的自动释放池,在主线程销毁是被自动释放