NSTextField 等待循环结束才更新
问题是:我有一些代码是这样的
otherWinController = [[NotificationWindowController alloc] init];
for (int i = 0; i < 10; i++) {
[otherWinController showMessage:[NSString stringWithFormat:@"%d", i]];
NSLog(@"%d", i);
sleep(1);
}
,其中 otherWinController 是 NSWindowController 的子类,当代码发生更改时我用它来更新我的窗口,而 alloc init 方法只是打开笔尖并显示窗口。 showMessage 是一种更改 NSTextView 以显示参数中的任何文本的方法。
在 NSLog 中,文本每秒都会变化,并且只数到十。然而,对于 showMessage 方法,文本整整十秒都是空白,然后只显示数字 10。有什么想法吗?
FTR,showMessage 方法根本
- (void)showMessage:(NSString *)text {
[[self message] setStringValue:text];
}
不重要,这是非常基本的。
Here's the problem: I have some code that goes like this
otherWinController = [[NotificationWindowController alloc] init];
for (int i = 0; i < 10; i++) {
[otherWinController showMessage:[NSString stringWithFormat:@"%d", i]];
NSLog(@"%d", i);
sleep(1);
}
where otherWinController is a subclass of NSWindowController that I am using to update my window as changes happen in code, and the alloc init method simply opens up the nib and shows the window. showMessage is a method that changes an NSTextView to display whatever text is in the parameter.
in the NSLog, the text changes every second and just counts to ten. However for the showMessage method, the text is blank for a full ten seconds and then just displays the number 10. any thoughts??
FTR, the showMessage method is simply
- (void)showMessage:(NSString *)text {
[[self message] setStringValue:text];
}
not that it should matter, that's pretty basic.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我认为通过调用 sleep(1) 你会阻塞主线程,它必须绘制你的更改。所以显示没有更新。任务管理器不会中断您的功能。在这种情况下,您不应该使用睡眠。请看一下 NSTimer 类。它有一个静态方法scheduledTimerWithTimeInterval,您应该使用它。
I think that by calling sleep(1) you block the main thread, which must draw your changes. So the display is not updated. The task manager will not interrupt your function. You shouldn't use sleep in this case. Please take a look at NSTimer class. It has a static method scheduledTimerWithTimeInterval, which you should use.
视图未更新直到运行循环结束;您的
for
循环不会让运行循环继续,因此您所做的所有视图更新都会在 for 循环退出后完成。您应该使用
NSTimer
或performSelector:withObject:afterDelay:
以类似循环的方式更改显示。然后你的计时器的操作将改变视图的图像:
你通常也不想使用睡眠,除非你在后台线程上,因为它会锁定 UI 的其余部分;你的用户将无法做任何事情,如果你睡得足够长,你就会得到旋转的沙滩球。
Views don't get updated until the end of the run loop; your
for
loop doesn't let the run loop continue, so all the view updates you make are just done after your for loop exits.You should either use an
NSTimer
orperformSelector:withObject:afterDelay:
to change the display in a loop-like fashion.Then your timer's action will change the view's image:
You also generally don't want to use
sleep
unless you're on a background thread, because it will lock up the rest of the UI; your user won't be able to do anything, and if you sleep long enough, you'll get the spinning beach ball.问题是您在 for 循环中阻塞了主线程,并且用户界面更新发生在主线程上。仅当包含
for
循环的方法完成执行后,主线程运行循环才会旋转(因此将发生用户界面更新)。如果您想每秒更新该文本字段,则应该使用计时器。例如,考虑到
otherWinController
是一个实例变量,请在类中声明一个counter
属性,并且:在同一个类中,实现每当触发时间时调用的方法:
The problem is that you’re blocking the main thread in your
for
loop and user interface updates happen on the main thread. The main thread run loop will only spin (and consequently user interface updates will take place) after the method containing thatfor
loop finishes executing.If you want to update that text field every second, you should use a timer. For instance, considering
otherWinController
is an instance variable, declare acounter
property in your class and:In the same class, implement the method that’s called whenever the time has been fired:
如果您明确地给运行循环一些运行时间,您可能可以在循环内实现所需的效果:
You can probably achieve the desired effect right inside your loop, if you explicitly give the run loop some time to run: