每当我的应用程序变得有点复杂时,它就会达到视图不像我希望的那样快速刷新的程度。
例如,如果我有一个播放器按钮,并且每当用户点击该按钮时,按钮将改变其图像,然后播放器将播放一些音乐,图像需要很长时间才能改变。
无论图像更改后是否存在“SetNeedsdisplay”,或者即使用户“preformSelectorOnMainThred”更改图像,也会发生这种情况。
我添加了代码快照,显示了我的意思:
- (IBAction)playButtonPressed:(id)sender {
//This is the image change, plus a small animation that should happen:
dispatch_async(dispatch_get_main_queue(), ^{
[self.playButtonImage setImage:[UIImage imageNamed:@"PlayDiscButtonPressedMC"]];
[[self superview] setNeedsDisplay];
[self performSelector:@selector(animationInsertDisk) withObject:nil];
});
//This is the methus that will call the player to start playing, by delegate.
[self performSelector:@selector(callDelegate) withObject:nil];;
}
发生的事情是,图像和动画的变化大约需要1-2秒才会发生,因为之后出现的是“callDelegate”!让我说我删除“callDelegate”然后图像和动画将发生在海峡之外!
我不明白为什么会发生这种情况,首先出现的代码是不是应该先发生? 是不是在主线程上发生了?
非常感谢任何帮助! 谢谢!!
答案 0 :(得分:0)
我会尝试解释
dispatch_async
计划块中的所有内容,以便将来使用。例如,如果您在按钮点按处理程序中调用dispatch_async
,则在方法结束并将控件返回给系统之前,代码将不会执行。
[self performSelector:@selector(callDelegate) withObject:nil];
与写作相同
[self callDelegate];
这是一个简单的方法调用。这是一个阻塞电话。如果调用需要一些时间,那么UI中的所有内容都必须等待(因为您从UI线程调用它)。
您的代码基本上与以下内容相同:
- (IBAction)playButtonPressed:(id)sender {
[self callDelegate];
dispatch_async(dispatch_get_main_queue(), ^{
[self.playButtonImage setImage:[UIImage imageNamed:@"PlayDiscButtonPressedMC"]];
//no need for this here. Don't try to fix bugs by adding random code.
//[[self superview] setNeedsDisplay];
//performSelector just calls the method, so a direct call is exactly the same
[self animationInsertDisk];
});
}
现在,我不确定你想要通过dispatch_async
实现什么。您希望动画立即启动,并且您已经在主线程上,所以只需执行
- (IBAction)playButtonPressed:(id)sender {
[self.playButtonImage setImage:[UIImage imageNamed:@"PlayDiscButtonPressedMC"]];
[self animationInsertDisk];
[self callDelegate];
}
但是,“滞后”可能是由于您从主线程启动播放器并阻塞主线程一段时间。我不确定你在[self callDelegate]
到底做了什么,但是dispatch_async
包裹这个电话会有所帮助。