Ios 主线程被阻塞时,MBProgressHUD不会按时显示
我正在开发一款使用cocos2d-x的游戏,我在旧设备上遇到了一个问题,比如ipad1,大型场景需要花费很多时间才能加载。 因此,场景转换可能需要几秒钟,因此我尝试在加载新场景时在场景转换之间实现“忙碌”动画。 我在IOS上使用MBProgressHUD,在android上使用ProgressDialog实现了这一点。 我决定不想立即开始显示此动画,而是可以将动画安排为在场景过渡开始后1-2秒开始,以便在较新的设备上根本不显示动画。 最初我做的是:Ios 主线程被阻塞时,MBProgressHUD不会按时显示,ios,multithreading,uikit,cocos2d-x,mbprogresshud,Ios,Multithreading,Uikit,Cocos2d X,Mbprogresshud,我正在开发一款使用cocos2d-x的游戏,我在旧设备上遇到了一个问题,比如ipad1,大型场景需要花费很多时间才能加载。 因此,场景转换可能需要几秒钟,因此我尝试在加载新场景时在场景转换之间实现“忙碌”动画。 我在IOS上使用MBProgressHUD,在android上使用ProgressDialog实现了这一点。 我决定不想立即开始显示此动画,而是可以将动画安排为在场景过渡开始后1-2秒开始,以便在较新的设备上根本不显示动画。 最初我做的是: - (void) showProgressDi
- (void) showProgressDialog: (int) runWithoutDelay
{
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(showProgressDialogAfterDelay) object:nil];
shouldShow = YES;
if (runWithoutDelay){
[self showProgressDialogAfterDelay];
}
else{
[self performSelector:@selector(showProgressDialogAfterDelay) withObject:nil afterDelay:delay];
}
}
- (void) showProgressDialogAfterDelay
{
if (shouldShow){
isShown = YES;
[progressHUD show:YES];
}
}
如果我通过场景过渡部分,我只会将shouldShow标志设置为false,并且不会启动动画。
问题在于,由于cocos2d-x场景转换是在主\ui线程中完成的,有时不在2秒后调用show方法,因此调用它最多需要6-8秒,有时甚至在我将标志设置为false后调用它。
据我所知,之所以会发生这种情况,是因为performSelector(我也尝试过的NSTimer也是如此)都是通过将调用放在线程运行循环队列中在同一线程上运行的。
我需要像performSelectorInBackground这样需要延迟的东西,所以我尝试在之后使用dispatch_(尽管我仍然不知道如何取消它,因为我需要在创建新计划时取消以前的计划)根据Xcode的日志,这看起来更准确,但即使日志说该方法在计划完成2秒后被调用,显示时间也需要5-8秒,有时甚至根本不会显示。
据我所知,如果我错了,请纠正我,这是因为MBProgressHUD对UI的更改必须发生在主\UI线程上,所以即使我调用[ProgressHUD show:YES]在后台线程上,UI的实际更新计划以某种方式在主线程上执行,因为它被卡在cocos2d-x东西上,所以只有在场景转换完成且为时已晚之后才开始显示
有办法解决这个问题吗?我是否可以安排它以延迟的方式开始,但在我需要的时候让它正确显示
我不明白的是,如果我毫不延迟地启动它,为什么即使主线程忙于cocos2d-x处理,动画也能顺利运行而不被卡住。我已经设法解决了这个问题
-(void)callHUD {
[progressHUD show];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self performSelectorOnMainThread:@selector(loadView) withObject:nil waitUntilDone:YES];
dispatch_async(dispatch_get_main_queue(), ^{
[progressHUD dismiss];
});
});
}
-(void)loadView {
//Perform your segue or transition which needs to load
}
希望这能对您有所帮助。这里的问题不在于UI,而在于资源加载(或任何需要很长时间的操作)在主线程上运行,从而阻塞了它。例如,在cocos2diphone中,有几种“异步”方法可以在背景中加载纹理和精灵帧,以允许播放前景加载动画。这就是你需要做的。嗨,谢谢你的快速回复。我知道主要的问题是我在UI线程上运行了很多非UI的东西,我在写问题时试图简单化,我运行的平台很大,不是我自己写的,在我必须处理这个问题的时间范围内,不可能做这种改变。所以目前这不是一个选项,我是否可以用另一种方式处理它?i、 我知道那里的工作时间更长了,但是谢谢你的回复:)我想可能下一个遇到这个问题的人会看到这个帖子!:)我自己也有这个问题,并为此制定了自己的代码。