使用“while循环”或“for循环”来驱动线程中的NSRunLoop

时间:2014-01-31 04:02:39

标签: ios objective-c nsrunloop

我对如何在线程中使用NSRunLoop有一些疑问。在Apple的线程编程指南中,它提到“你的代码提供了用于实现运行循环的实际循环部分的控制语句 - 换句话说,你的代码提供了驱动运行循环的while或for循环。”因此,当使用NSURLConnection在新线程中异步加载数据时,我编写以下代码并且它可以工作:

...
....
NSURLConnection* connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];
[NSThread detachNewThreadSelector:@selector(downloadThread:) toTarget:self withObject:nil];
....
...

选择器“downloadThread”是新线程的入口点,以下是“downloadThread”代码:

- (int) downloadThread:(id)option {
    BOOL ret;
    [connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [connection start];
    while (finished == NO) {
        ret = [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
    }
    return 1;
}

这里有一个问题,NSRunLoop是一个循环,为什么我们应该使用循环语句“while(finish == NO)”来控制NSRunLoop?尽管苹果的文档提到了这一点,但我只是不明白。另一方面,当使用计时器时,我们不需要循环语句来控制NSRunLoop,它可以工作,就像这样:

...
....
NSTimer* _timer = [NSTimer timerWithTimeInterval:1 target:object selector:@selector(timerFunc) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSDefaultRunLoopMode];
[_timer fire];
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
....
...

那么,在什么情况下我们应该使用循环语句来控制NSRunLoop?

1 个答案:

答案 0 :(得分:0)

阅读-[NSRunLoop runMode:beforeDate:]的{​​{3}}。该方法在处理单个输入源后返回。因此,如果您希望继续处理输入源,直到某个特定事件发生,您必须循环它。

我不确定定时器代码来自何处,但无法保证调用-runMode:beforeDate:一次将允许定时器触发。此外,-runMode:beforeDate:不会因为计时器被触发而返回。所以,这个代码对我来说至少有两个错误。