我找到了有趣的东西..下面的代码没有显示@“One”,并且在3秒延迟后显示@“Two”.. 我认为@“One”需要显示然后3秒延迟然后@“Two”需要弹出.. 我错了吗?
self.statusLabel.text = @"One";
sleep(3);
self.statusLabel.text = @"Two";
谢谢..
答案 0 :(得分:7)
如果您在主线程上执行此操作,sleep(3)
将阻止它,冻结应用程序3秒钟。事件处理(包括重新绘制UI等内容)将不会发生,直到结束。
要获得您期望的结果,请尝试以下方法:
[self.statusLabel setText:@"One"];
[self.statusLabel performSelector:@selector(setText:)
withObject:@"Two"
afterDelay:3.0];
第一次更改,然后将执行第二次更改的调用排队,以便将来发生。然后将控制权返回给OS以进行任何必要的重绘。
答案 1 :(得分:2)
你对事情应该如何运作的看法是错误的。
self.statusLabel.text = @"One";
这会将statusLabel字段的值设置为“One”。这不会立即绘制到屏幕上。相反,标签将标记为需要显示。在当前运行循环周期结束时,将绘制标记为需要显示的所有视图,然后将其内容刷新到屏幕。
接下来你做:
sleep(3);
self.statusLabel.text = @"Two";
这会阻塞主线程3秒钟(永远不会返回运行循环来完成上述工作),然后将值更改为“Two”,再次将视图标记为需要显示。
当它最终被绘制并刷新到屏幕时,当前值为“2”。
很难就你应该做什么提出更具体的建议,因为目前尚不清楚你是否正在尝试解决一个真正的问题,或者只是为了更多地了解这些框架而进行实验。
但你几乎不应该使用睡眠,你肯定不应该在睡眠中阻塞主线程几秒钟。
答案 2 :(得分:1)
你错了......
以这种方式思考:当你在一个块中执行代码时,你会告诉iOS你想做什么。在将控制权传递回操作系统后,它实际上只是实现您的指令。
您的代码阻止了主线程(这是一件非常糟糕的事情)。
您需要做的是将标签设置为“One”,然后设置一个将在三秒钟内启动的计时器。计时器中的代码会将标签的文本设置为“两个”。