去年我写了一个针对10.10(优胜美地)的SpriteKit应用程序。一切都运行良好,但当我今年升级到El Capitan时,它冻结在一个特定的位置。这是一个很难诊断的问题,因为有很多代码,所以我会尝试尽可能具有描述性。我还创建了YOUTUBE screen recording问题。
应用目的
该应用程序基本上是我为我所教的学校的锦标赛创建的排行榜。当应用程序启动时,它会转到LeaderboardScene
场景并显示排行榜。
该应用程序在其余时间停留在此场景中。说“#34;战斗"是一个按钮。按下它时会创建一个叠加层,并以视频形式显示两个将面对面的学生(SKVideoNode
)。
视频会持续播放,应用的用户最终会点击哪个学生赢得匹配,然后重叠将从场景中移除,应用再次显示排行榜。
高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];
}];
我必须以另一种方式处理模糊,或者只是完全删除模糊。