Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 主线程被阻塞时,MBProgressHUD不会按时显示_Ios_Multithreading_Uikit_Cocos2d X_Mbprogresshud - Fatal编程技术网

Ios 主线程被阻塞时,MBProgressHUD不会按时显示

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

我正在开发一款使用cocos2d-x的游戏,我在旧设备上遇到了一个问题,比如ipad1,大型场景需要花费很多时间才能加载。 因此,场景转换可能需要几秒钟,因此我尝试在加载新场景时在场景转换之间实现“忙碌”动画。 我在IOS上使用MBProgressHUD,在android上使用ProgressDialog实现了这一点。 我决定不想立即开始显示此动画,而是可以将动画安排为在场景过渡开始后1-2秒开始,以便在较新的设备上根本不显示动画。 最初我做的是:

- (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处理,动画也能顺利运行而不被卡住。

我已经设法解决了这个问题

  • 创建一个普通方法,在其中调用progressHUD并调用第二个

  • 创建第二种方法,在其中执行耗时的工作(加载视图)

  • 在主线程上执行该方法

  • 样本:

    -(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、 我知道那里的工作时间更长了,但是谢谢你的回复:)我想可能下一个遇到这个问题的人会看到这个帖子!:)我自己也有这个问题,并为此制定了自己的代码。