Как работает предварительная загрузка SKTextureAtlasTextureAtlases: withCompletionHandler?

Я пытаюсь понять, в чем разница между этими двумя примерами и как работает 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

}];

person Whirlwind    schedule 30.03.2015    source источник


Ответы (1)


Вы можете выполнять предварительную загрузку в фоновом режиме, но вопрос в том, зачем вам это? Скорее всего, ваша игра не может начать играть, пока не будут загружены все необходимые ресурсы, поэтому пользователю все равно придется ждать.

Вы можете предварительно загрузить любые ресурсы, необходимые для запуска игры, и загрузить в фоновом режиме любые дополнительные ресурсы, которые могут вам понадобиться во время более поздней игры. Такие обстоятельства действительно требуются только в очень сложных играх, а не на платформе iOS.

Что касается вашего вопроса о загрузке в фоновом режиме во время игры, однозначного ответа нет. Все зависит от того, насколько велика нагрузка, загрузка вашего процессора и т. д. Попробуйте и посмотрите, что произойдет, потому что это звучит так, как будто вы задаете вопросы по проблемам, которые вы не пробовали в первую очередь.

Если вы действительно заинтересованы в фоновых задачах, помните, что вы можете добавить блок завершения в свои пользовательские методы следующим образом:

-(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();
            }
        });
    });
}
person sangony    schedule 31.03.2015
comment
Привет Сангони, спасибо за подсказки! На самом деле я как раз собирался написать ответ на свой вопрос, но неважно. Я пробовал все. В первом примере обработчик завершения preloadTextureAtlases вызывается в фоновом потоке, чего я не ожидал. Из-за этого setupScene вызывается в фоновом режиме. Во втором примере настройка сцены выполняется в основном потоке (dispatch_get_main_queue). Я думал, что между этими двумя примерами нет никакой разницы, но она есть. Вот одна похожая тема stackoverflow. ком/вопросы/22534088/ - person Whirlwind; 31.03.2015
comment
Я предварительно загружаю активы в фоновом режиме из-за анимации загрузки... Это единственная причина. В противном случае приложение зависает примерно на 0,5 или 1 секунду, а анимация загрузки останавливается. - person Whirlwind; 31.03.2015
comment
В документах Apple для preloadTextureAtlases явно указано: SpriteKit создает фоновую задачу, которая загружает данные текстуры из всех указанных атласов. Затем SpriteKit возвращает управление вашей игре. После загрузки атласов вызывается обработчик завершения. - person MoDJ; 08.09.2016
comment
Вы можете выполнять предварительную загрузку в фоновом режиме, но вопрос в том, зачем вам это? потому что уровни могут быть большими, и вам нужно предварительно загрузить их по требованию. Нельзя сразу загружать в память огромное количество текстур. Вот почему. - person damirstuhec; 24.11.2016
comment
@damirstuhec - Попробуйте прочитать мой ответ полностью, прежде чем комментировать его. - person sangony; 24.11.2016