【问题标题】:How does SKTextureAtlas preloadTextureAtlases: withCompletionHandler works?SKTextureAtlas preloadTextureAtlases: withCompletionHandler 是如何工作的?
【发布时间】:2015-03-30 23:19:17
【问题描述】:

我试图弄清楚这两个示例之间的区别以及 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 objective-c sprite-kit grand-central-dispatch sktextureatlas


    【解决方案1】:

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

    您可以预加载启动游戏所需的任何资产,并在后台加载您在以后玩游戏时可能需要的任何其他资产。这种情况实际上只在非常复杂的游戏中需要,而不是在 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();
                }
            });
        });
    }
    

    【讨论】:

    • 嗨,桑戈尼,感谢您的提示!实际上,我正要为自己的问题写一个答案,但没关系。我什么都试过了。在第一个示例中,preloadTextureAtlases 的完成处理程序在后台线程中调用,这是我没有预料到的。因此,setupScene 在后台被调用。在第二个示例中,场景设置在主线程 (dispatch_get_main_queue) 上完成。我认为这两个示例之间没有区别,但是有。这是一个类似的主题stackoverflow.com/questions/22534088/…
    • 我在后台预加载资产,因为加载动画......这是唯一的原因。否则,应用程序会冻结大约 0.5 或 1 秒并停止加载动画。
    • preloadTextureAtlases 的 Apple 文档明确指出:“SpriteKit 创建一个后台任务,从所有指定的图集中加载纹理数据。然后,SpriteKit 将控制权返回给您的游戏。加载图集后,你的完成处理程序被调用。”
    • "您可以在后台预加载,但问题是您为什么要这样做?"因为级别可能很大,您必须按需预加载。您不能一次将大量纹理预加载到内存中。这就是为什么。
    • @damirstuhec - 在评论之前尝试阅读我的整个答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多