SKTextureAtlas preloadTextureAtlases: withCompletionHandler 是如何工作的?

How does SKTextureAtlas preloadTextureAtlases: withCompletionHandler works?

我试图找出这两个示例之间的区别以及 preloadTextureAtlases :withCompletionHandler 的工作原理。这是代码:

//GameScene.m
-(void)didMoveToView:(SKView *)view {

   //First I create an animation, just a node moving from one place to another and backward.

   //Then I try to preload  two big atlases



[SKTextureAtlas preloadTextureAtlases:@[self.atlasA, self.atlasB] withCompletionHandler:^{   
               [self setupScene:self.view];   
       }];

我想 preloadTextureAtlases 在后台线程上加载是因为我的动画很流畅?

但是从后台线程调用 preloadTextureAtlases 有什么区别(或者它可能有问题)吗?像这样:

//GameScene.m
    - (void)loadSceneAssetsWithCompletionHandler:(CompletitionHandler)handler {
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
      [SKTextureAtlas preloadTextureAtlases:@[self.atlasA, self.atlasB] withCompletionHandler:^{

                dispatch_async(dispatch_get_main_queue(), ^{

                  [self setupScene:self.view];
                });  
            }];

            if (!handler){return;}
            dispatch_async(dispatch_get_main_queue(), ^{
                handler();
            });
        });
    }

然后从 didMoveToView 调用这个方法:

    [self loadSceneAssetsWithCompletionHandler:^{

    NSLog(@"Scene loaded");
    // Remove loading animation and stuff

}];

您可以在后台预加载,但问题是为什么要这样做?有可能您的游戏需要等到所有必需的资产都加载完毕后才能开始播放,因此无论如何用户都必须等待。

您可以预加载启动游戏所需的任何资产,并在后台加载您在以后玩游戏时可能需要的任何其他资产。这种情况实际上只在非常复杂的游戏中才需要,而不是在 iOS 平台上。

关于你关于游戏进行时后台加载的问题,没有明确的答案。这完全取决于负载有多大,您的 CPU 负载等...尝试一下,看看会发生什么,因为这听起来像是您在问您没有先尝试过的问题。

如果您真的想处理后台任务,请记住您可以像这样向自定义方法添加完成块:

-(void)didMoveToView:(SKView *)view {
    NSLog(@"start");

    [self yourMethodWithCompletionHandler:^{
        NSLog(@"task done");
    }];

    NSLog(@"end");
}

-(void)yourMethodWithCompletionHandler:(void (^)(void))done; {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        // a task running another thread
        for (int i=0; i<100; i++) {
            NSLog(@"working");
        }

        dispatch_async(dispatch_get_main_queue(), ^{
            if (done) {
                done();
            }
        });
    });
}