在Objective-C/Cocoa中,与Java的Thread.sleep()相当的是什么?

122

在Java中,你可以使用Thread.sleep()暂停当前线程的执行一段时间。Objective-C中是否有类似的方法呢?

6个回答

164

8
谢谢!供以后参考,实际上定义是 +[NSThread sleepForTimeInterval:] (因此使用方式类似于 [NSThread sleepForTimeInterval:0.1])。 - TinkerTank
太好了,谢谢!我刚刚完成了我的动画模块,效果非常完美。 - RileyE
在主线程上睡觉怎么样? - stackunderflow
1
这没什么区别;主线程只是一个线程。不过,在主线程上睡觉通常是个坏主意,因为它会使你的程序无法响应。 - smorgan
4
对于那些想知道的人,[NSThread sleepForTimeInterval:]与[[NSThread currentThread] sleepForTimeInterval:]是相同的。 - pnizzle

111

在Java中睡眠一秒钟:

Thread.sleep(1000);

在 Objective C 中睡眠 一秒钟:

[NSThread sleepForTimeInterval:1.0f];

41
为什么你在睡觉?当你睡觉时,会阻塞UI并且也会阻止任何不在其他线程中的后台URL加载(使用NSURL异步方法仍会在当前线程上操作)。
很可能你真正想要的是performSelector:withObject:AfterDelay方法。这是NSObject上的一个方法,可用于稍后调用方法 - 它安排了一个将在以后时间执行的调用,但线程处理的所有其他内容(如UI和数据加载)仍将继续进行。

44
睡眠对我来说很有用,因为我可以利用它模拟一些网络延迟,以确保我的应用程序能够正确响应。目前,我正在对本地Web服务器进行测试,所以一切基本上是瞬间完成的。 - brantonb
7
睡眠不是测试网络延迟的正确方法。查看此问题的答案https://dev59.com/7UnSa4cB1Zd3GeqPPZcT,以了解如何在模拟器中测试网络的可变速度。由于睡眠主线程会阻塞一切,因此您根本没有模拟网络延迟,而是暂停应用程序。 - Kendall Helmstetter Gelner
1
如果您睡眠了一段时间,您的线程将与睡眠前完全相同,这并不是一个好的测试,因为在现实世界中,您的应用程序将会处理数据而不是休眠。这就是为什么重要的是要找出如何在没有依赖于休眠的情况下进行测试。 - Kendall Helmstetter Gelner
这真的取决于你要测试什么。在我的情况下,我只需要交互式模拟一个缓慢加载的 Web 服务调用。没有必要模拟 CPU 使用率。这里描述的各种替代睡眠的方法对我的目的来说都过于复杂了。 - Andrew Rondeau
不管你正在测试什么,使用sleep()都无法模拟缓慢加载的网络服务调用。实际上,这是你在测试该场景时可能做的最糟糕的事情,因为你所在的线程将被挂起,而不是像在缓慢的网络服务调用期间那样继续处理其他任务,你将掩盖所有可能存在的问题,对于正在运行的代码来说,它看起来就像你的调用立即完成了,而不是变慢了。使用Network Link Conditioner工具(Mac)来测试缓慢的调用。 - Kendall Helmstetter Gelner
显示剩余10条评论

9
当然,你也可以使用标准的Unix sleep()和usleep()调用。如果是编写Cocoa应用程序,建议使用[NSThread sleepForTimeInterval:]。

6
如果你使用NSThread的sleepForTimeInterval(注释代码)来进行睡眠,获取数据将被阻塞。但使用+[NSThread sleepForTimeInterval:](checkLoad方法)则不会阻塞获取数据。
以下是我的示例代码:
- (void)viewDidAppear:(BOOL)animated
{
//....
//show loader view
[HUD showUIBlockingIndicatorWithText:@"Fetching JSON data"];
//    while (_loans == nil || _loans.count == 0)
//    {
//        [NSThread sleepForTimeInterval:1.0f];
//        [self reloadLoansFormApi];
//        NSLog(@"sleep ");
//    }
[self performSelector:@selector(checkLoad) withObject:self afterDelay:1.0f];
}

-(void) checkLoad
{
    [self reloadLoansFormApi];
    if (_loans == nil || _loans.count == 0)
    {
        [self performSelector:@selector(checkLoad) withObject:self afterDelay:1.0f];
    } else
    {
        NSLog(@"size %d", _loans.count);
        [self.tableView reloadData];
        //hide the loader view
        [HUD hideUIBlockingIndicator];
    }
}

0

在编程中,usleep()函数也可以用来暂停当前线程。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接