使用过多CPU的SpriteKit应用程序

时间:2016-12-28 20:14:50

标签: sprite-kit cpu-usage osx-elcapitan

去年我写了一个针对10.10(优胜美地)的SpriteKit应用程序。一切都运行良好,但当我今年升级到El Capitan时,它冻结在一个特定的位置。这是一个很难诊断的问题,因为有很多代码,所以我会尝试尽可能具有描述性。我还创建了YOUTUBE screen recording问题。

应用目的
该应用程序基本上是我为我所教的学校的锦标赛创建的排行榜。当应用程序启动时,它会转到LeaderboardScene场景并显示排行榜。

LeaderboardScene

该应用程序在其余时间停留在此场景中。说“#34;战斗"是一个按钮。按下它时会创建一个叠加层,并以视频形式显示两个将面对面的学生(SKVideoNode)。

enter image description here 视频会持续播放,应用的用户最终会点击哪个学生赢得匹配,然后重叠将从场景中移除,应用再次显示排行榜。

高CPU的潜在原因
播放视频:通常叠加显示视频,但我还创建了一个选项,其中加载静止图像而不是视频以防我遇到问题。无论是加载图像还是视频,CPU使用率都非常高。

以下是一些最有可能导致此问题的代码:

LeaderboardScene.m

//when the sword button is pressed it switches to the LB_SHOW_VERSUS_SCREEN state
-(void) update:(NSTimeInterval)currentTime {
    switch (_leaderboardState) {
        ...
        case LB_SHOW_VERSUS_SCREEN: { //Case for "Versus Screen" overlay
            [self showVersusScreen];
            break;
        }
        case LB_CHOOSE_WINNER: {
            break;
        }
        default:
            break;
    }
}

...

//sets up the video overlay
-(void) showVersusScreen {
    //doesn't allow the matchup screen to pop up until the producer FLASHING actions are complete
    if ([_right hasActions] == NO) {
        [self addChild:_matchup]; //_matchup is an object from the Matchup.m class
        NSArray *producers = @[_left, _right];
        [_matchup createRound:_round WithProducers:producers VideoType:YES]; //creates the matchup with VIDEO
        //[_matchup createRound:_round WithProducers:producers VideoType:NO]; //creates the matchup without VIDEO
        _leaderboardState = LB_CHOOSE_WINNER;
    }
}

Matchup.m

//more setting up of the overlay
-(void) createRound:(NSString*)round WithProducers:(NSArray*)producers VideoType:(bool)isVideoType {
    SKAction *wait = [SKAction waitForDuration:1.25];
    [self loadSoundsWithProducers:producers];

    [self runAction:wait completion:^{ //resets the overlay
        _isVideoType = isVideoType;
        [self removeAllChildren];
        [self initBackground];
        [self initHighlightNode];
        [self initOutline];
        [self initText:round];

        if (_isVideoType)
            [self initVersusVideoWithProducers:producers]; //this is selected
        else
            [self initVersusImagesWithProducers:producers];

        [self animationSequence];

        _currentSoundIndex = 0;
        [self playAudio];
    }];
}

...

//creates a VersusSprite object which represents each of the students
-(void) initVersusVideoWithProducers:(NSArray*)producers {
    Producer *left = (Producer*)[producers objectAtIndex:0];
    Producer *right = (Producer*)[producers objectAtIndex:1];

    _leftProducer = [[VersusSprite alloc] initWithProducerVideo:left.name LeftSide:YES];
    _leftProducer.name = left.name;
    _leftProducer.zPosition = 5;
    _leftProducer.position = CGPointMake(-_SCREEN_WIDTH/2, _SCREEN_HEIGHT/3);
    [self addChild:_leftProducer];

    _rightProducer = [[VersusSprite alloc] initWithProducerVideo:right.name LeftSide:NO];
    _rightProducer.name = right.name;
    _rightProducer.zPosition = 5;
    _rightProducer.xScale = -1;
    _rightProducer.position = CGPointMake(_SCREEN_WIDTH + _SCREEN_WIDTH/2, _SCREEN_HEIGHT/3);
    [self addChild:_rightProducer];
}

VersusSprite.m

-(instancetype) initWithProducerVideo:(NSString*)fileName LeftSide:(bool)isLeftSide {
    if (self = [super init]) {
        _isVideo = YES;
        _isLeftSide = isLeftSide;
        self.name = fileName;
        [self initVideoWithFileName:fileName]; //creates videos
        [self addProducerLabel];
    }
    return self;
}

...

//creates the videos for the VersusSprite
-(void) initVideoWithFileName:(NSString*)fileName {
    NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDesktopDirectory, NSUserDomainMask, YES);
    NSString *desktopPath = [paths objectAtIndex:0];
    NSString *resourcePath = [NSString stringWithFormat:@"%@/vs", desktopPath];
    NSString *videoPath = [NSString stringWithFormat:@"%@/%@.mp4", resourcePath, fileName];
    NSURL *fileURL = [NSURL fileURLWithPath:videoPath];
    AVPlayer *avPlayer = [[AVPlayer alloc] initWithURL:fileURL];

    _vid = [SKVideoNode videoNodeWithAVPlayer:avPlayer];
    //[_vid setScale:1];
    [self addChild:_vid];
    [_vid play];

    avPlayer.actionAtItemEnd = AVPlayerActionAtItemEndNone;

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(playerItemDidReachEnd:)
                                                 name:AVPlayerItemDidPlayToEndTimeNotification
                                               object:[avPlayer currentItem]];
}

//used to get the videos to loop
- (void)playerItemDidReachEnd:(NSNotification *)notification {
    AVPlayerItem *p = [notification object];
    [p seekToTime:kCMTimeZero];
}

更新
这个问题已经确定,并且对我的项目非常具体,所以不幸的是,它可能不会帮助其他任何人。当点击"剑"表示" Battle"的图标,场景变得模糊,然后将叠加层置于其上。模糊发生在后台线程上,如下所示:

[self runAction:[SKAction waitForDuration:1.5] completion:^{
    [self blurSceneProgressivelyToValue:15 WithDuration:1.25];
}];

我必须以另一种方式处理模糊,或者只是完全删除模糊。

0 个答案:

没有答案