NSRunloop 的用法

来源:互联网 发布:邢台seo外包 编辑:程序博客网 时间:2024/06/01 08:58

今天突然才之间才意识到NSTimer这样的运行方式,是在多线程中实现的循环还是在主线程中去实现的呢。当然不可能是在主线程中的while那么简单,那样什么都干不了,简单看了下NSTimer是以同步方式运行的。时间到了,消息发出后,ontimer的函数是在主线程上调用的。

我们会经常看到这样的代码:

  1. - (IBAction)start:(id)sender 

  2. pageStillLoading = YES; 
  3. [NSThread detachNewThreadSelector:@selector(loadPageInBackground:)toTarget:self withObject:nil]; 
  4. [progress setHidden:NO]; 
  5. while (pageStillLoading) { 
  6. [NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; 

  7. [progress setHidden:YES]; 
复制代码
这段代码很神奇的,因为他会“暂停”代码运行,而且程序运行不会因为这里有一个while循环而受到影响。在[progress setHidden:NO]执行之后,整个函数想暂停了一样停在循环里面,等loadPageInBackground里面的操作都完成了以后才让[progress setHidden:YES]运行。这样做就显得简介,而且逻辑很清晰。如果你不这样做,你就需要在loadPageInBackground里面表示load完成的地方调用[progress setHidden:YES],显得代码不紧凑而且容易出错。
[iGoogle有话说:应用程序框架主线程已经封装了对NSRunLoop runMode:beforeDate:的调用;它和while循环构成了一个消息泵,不断获取和处理消息;可能大家会比较奇怪,既然主线程中已经封装好了对NSRunLoop的调用,为什么这里还可以再次调用,这个就是它与Windows消息循环的区别,它可以嵌套调用.当再次调用while+NSRunLoop时候程序并没有停止执行,它还在不停提取消息/处理消息.这一点与Symbian中Active Scheduler的嵌套调用达到同步作用原理是一样的.]

记录一篇帖子:http://www.cocoachina.com/bbs/read.php?tid-38499.html


还有一个使用的例子:

-(void)backgroundThreadStarted {

NSAutoreleasePool* thePool = [[NSAutoreleasePool alloc] init];

// create a scheduled timer

NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(backgroundThreadFire:) userInfo:nil repeats:YES];

[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];

m_isBackgroundThreadToTerminate = NO;

// create the runloop

double resolution = 300.0;

BOOL isRunning;

do {

// run the loop!

NSDate* theNextDate = [NSDate dateWithTimeIntervalSinceNow:resolution];

isRunning = [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopModebeforeDate:theNextDate];

// occasionally re-create the autorelease pool whilst program is running

[thePool release];

thePool = [[NSAutoreleasePool alloc] init];

} while(isRunning==YES && m_isBackgroundThreadToTerminate==NO);

[thePool release];

}

-(void)backgroundThreadFire:(id)sender {

// do repeated work every one second here

// when thread is to terminate, call [self backgroundThreadTerminate];

}

-(void)backgroundThreadTerminate {

m_isBackgroundThreadToTerminate = YES;

CFRunLoopStop([[NSRunLoop currentRunLoop] getCFRunLoop]);

}

NSTimer、 NSTask、 NSThread 和 NSRunloop 之间的区别


http://www.helmsmansoft.com/index.php/archives/904