SpriteKit SKAction runBlock如何影响FPS性能?

时间:2015-01-14 15:08:36

标签: ios performance sprite-kit avaudioplayer skaction

我正在使用SKAction类别播放AVAudioPlayer声音 - 它看起来像这样:

+ (SKAction *)atw_playSoundWithData:(NSData *)soundData {
    // If AVAudioSession is inactive do not make any sound
    if ([BAPAppDelegate isAudioSessionActive] == NO) {
        return [SKAction runBlock:^{}];
    } else {
        // Create playSoundAction which starts on concurrent queue to gain speed
        return [SKAction runBlock:^{
            NSError *error;
            AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithData:soundData error:&error];

            if (!error) {
                audioPlayer.numberOfLoops = 0;
                [audioPlayer play];

                // Cache audioPlayer to avoid autoreleasing before play end
                [SKAction atw_cacheAudioPlayer:audioPlayer];
            }
           //NSLog(@"%s  Added: %@ withError: %@, Cache: %lu", __PRETTY_FUNCTION__, audioPlayer, error, (unsigned long)[sATWAudioPlayersCache count]);
        } queue:sATWAudioPlayersCacheQueue];
    }
}

缓存AVAudioPlayer是为了避免过早发布玩家 - 这是方法:

static NSMutableSet *sATWAudioPlayersCache; // It's our cache
static dispatch_queue_t sATWAudioPlayersCacheQueue; // It's our concurrent queue of audioPlayers that are playing
+ (void)atw_cacheAudioPlayer:(AVAudioPlayer *)audioPlayer {

    // Init cache for the first time
    if (sATWAudioPlayersCache == nil) {
        sATWAudioPlayersCache = [[NSMutableSet alloc] initWithCapacity:1];
        sATWAudioPlayersCacheQueue = dispatch_queue_create("com.AppThatWorks.SKAction+ATWSound.sATWAudioPlayersCacheQueue", DISPATCH_QUEUE_CONCURRENT);
    }

    if (audioPlayer == nil) return;

    dispatch_barrier_async(sATWAudioPlayersCacheQueue, ^{
        [sATWAudioPlayersCache addObject:audioPlayer];
    });

    // Set delayed cache clear event for that audioPlayer (with barrier also to ensure exclusive access)
    double delay = [audioPlayer duration]+0.1; // +0.1 second buffer for safe sound end
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_SEC));
    dispatch_after(popTime, sATWAudioPlayersCacheQueue, ^(void){
        dispatch_barrier_async(sATWAudioPlayersCacheQueue, ^{
            // For safety sake, stop audioPlayer to avoid potential bad access while removing/autoreleasing.
            // It could happen if delay was nearly equal to [audioPlayer duration] (i.e. released while stopping).
            [audioPlayer stop];
            [sATWAudioPlayersCache removeObject:audioPlayer];
            //NSLog(@"%s Removed: %@ , Cache: %lu", __PRETTY_FUNCTION__, audioPlayer, (unsigned long)[sATWAudioPlayersCache count]);
        });
    });
}

我发现每秒播放大约10个声音会影响FPS从60到有时甚至49 fps(不幸的是,它非常明显),尽管CPU仍然保持在其使用率的20%。因为跳过播放声音会修复FPS性能,这就是为什么我的问题来自:

问题: SKAction runBlock如何影响FPS? (或者我的GCD解决方案/ AVAudioPlayer如何做到这一点?)

0 个答案:

没有答案