有点新的iPhone编程并正在尝试线程
- (void)viewDidLoad {
[super viewDidLoad];
[NSThread detachNewThreadSelector:@selector(changeMain) toTarget:self withObject:nil];
[NSThread detachNewThreadSelector:@selector(changeThread) toTarget:self withObject:nil];
}
- (void)changeMain{
NSAutoreleasePool* arp = [[NSAutoreleasePool alloc] init];
for (int i = 0; i < 1000000; i++) {
[mainValue setText:[NSString stringWithFormat:@"%d",i]];
[self.view setNeedsDisplay];
}
[arp release];
}
- (void)changeThread{
NSAutoreleasePool* arp = [[NSAutoreleasePool alloc] init];
for (int i = 0; i < 1000000; i++) {
[threadValue setText:[NSString stringWithFormat:@"%d",i]];
[self.view setNeedsDisplay];
}
[arp release];
}
mainValue和threadValue都只是UILabels。我希望这个运行并看到两个标签都运行到999999但是它开始时的数字很低(当我初步刷新时我假设它是什么),暂停一下,然后更新到999999.我在想屏幕只是不爽快。
这是对的吗?我做错了吗?
答案 0 :(得分:1)
setNeedsDisplay
消息会触发重绘,但只会在主线程下次活动时发生。因此,您的侧线程会触发一百万次重绘,但它们会排队等候。一旦主线程继续,它就会将所有请求“折叠”为一次重绘。
很可能setNeedsDisplay
只设置一个在主循环的每次运行期间检查一次的标志,因此将其设置为1000000为true不会影响任何内容。尝试让“工作线程”在每次迭代后保持睡眠状态,以便为主线程重新绘制一些时间。
答案 1 :(得分:1)
setNeedsDisplay
。所以我建议使用以下结构:
[threadValue performSelectorOnMainThread:@selector(setText:) withObject:[NSString stringWithFormat:@"%d",i] waitUntilDone:YES];
附加说明:
1. 100000次运行可以溢出主线程队列,因此某些值将消失
2.您也可以使用waitUntilDone:NO
答案 2 :(得分:1)
不要将for()
用于动画。 for
将在同一“框架”中处理。也许只有一个ivar i
而在changeMain
你可以有if (i<10000) { mainValue.text = [NSString stringWithFormat:@"%d",i]; i++;}
或类似的东西。这样setText
每个“帧”只发生一次。
答案 3 :(得分:0)
我不确定这是否有效,但您可以尝试强制setNeedsDisplay
方法在主线程上执行,例如使用[self performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:YES]
。这应该(希望,我没有测试它!)每次增量后更新视图。您也可以尝试设置waitUntiDone:NO
,但我不确定会发生什么。