我正在使用Obj-C和Apple的SpriteKit框架开发iOS游戏。我的主要测试设备是iPad2(型号为#MC773X / A,运行iOS8.1)。我的游戏在这个设备上运行顺畅,除了单个"口吃"大约60-120秒。此时应用程序滞后约150-300毫秒/ 10-20帧。
我在iPhone6 +(运行iOS8.4的型号为#MGAJ2X / A)上测试了相同的游戏应用程序,但似乎没有这个问题。
我原本以为它与我的游戏应用程序资源管理有关,后来可能是调试链接本身......所以我创建了以下测试应用程序。它只是一个空白屏幕,记录的时间超过20毫秒。它可以选择在没有调试链接的情况下登录屏幕(使用SKLabelNodes)进行测试。
这个简单的测试应用程序在大约60s标记处显示出与iPad2相同的断言(内置在调试/发布中,有/无调试)。 iPhone 6+并没有显示出口吃的行为。
从iOS的新SpriteKit游戏模板开始(我使用的是Xcode 6.4,但我看到了与早期版本相同的错误 - Xcode 6.something):
在GameViewController.m中:
//scene.scaleMode = SKSceneScaleModeAspectFill;
scene.scaleMode = SKSceneScaleModeResizeFill;
将GameScene.m替换为:
#import "GameScene.h"
#define LOG_TO_SCREEN
static int dtLogCounter = 1;
#ifdef LOG_TO_SCREEN
static const int dtLogLabelNum = 10; //5;
#endif
@interface GameScene ()
@property (nonatomic) CFTimeInterval prevTime;
@property (nonatomic) CFTimeInterval startTime;
#ifdef LOG_TO_SCREEN
@property (strong, nonatomic) SKLabelNode *timeLabel;
@property (strong, nonatomic) NSArray *dtLogLabels;
#endif
@end
@implementation GameScene
-(void)didMoveToView:(SKView *)view
{
#ifdef LOG_TO_SCREEN
CGFloat screenWidth = view.bounds.size.width;
_timeLabel = [SKLabelNode labelNodeWithFontNamed:@"Courier"];
_timeLabel.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeRight;
_timeLabel.fontSize = 16.0;
_timeLabel.position = CGPointMake(screenWidth - 7.0, 28.0);
[self addChild:_timeLabel];
NSMutableArray *dtLogLabels = [NSMutableArray arrayWithCapacity:dtLogLabelNum];
for (int i = 0; i < dtLogLabelNum; i++)
{
SKLabelNode *dtLogLabel = [SKLabelNode labelNodeWithFontNamed:@"Courier"];
dtLogLabel.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeRight;
dtLogLabel.fontSize = 16.0;
dtLogLabel.position = CGPointMake(screenWidth - 7.0, 100.0 + 25*i);
[self addChild:dtLogLabel];
[dtLogLabels addObject:dtLogLabel];
}
_dtLogLabels = [NSArray arrayWithArray:dtLogLabels];
#endif
_prevTime = _startTime = CACurrentMediaTime();
}
-(void)update:(CFTimeInterval)currentTime
{
CFTimeInterval dt = currentTime - _prevTime;
_prevTime = currentTime;
CFTimeInterval gameTime = currentTime - _startTime;
#ifdef LOG_TO_SCREEN
_timeLabel.text = [NSString stringWithFormat:@"t:%.1f(c)", gameTime];
#endif
if (dt > 20e-3)
{
NSString *logStr = [NSString stringWithFormat:@"#%d:%.1f:%.0f ", dtLogCounter++, gameTime, dt*1000];
#ifdef LOG_TO_SCREEN
for (int i = dtLogLabelNum-1; i > 0; i--)
{
SKLabelNode *dtLogLabel = [_dtLogLabels objectAtIndex:i];
SKLabelNode *prevLabel = [_dtLogLabels objectAtIndex:i-1];
dtLogLabel.text = prevLabel.text;
}
SKLabelNode *firstDtLogLabel = [_dtLogLabels objectAtIndex:0];
firstDtLogLabel.text = logStr;
#else
NSLog(@"%@", logStr);
#endif
}
}
@end
我对使用时间分析仪器感到满意,但在这种情况下,我认为它不是特别有用。它在口吃持续时间内没有显示活动。 (图像1) (不幸的是,我是一张全新的海报,因此无法内联图片)
这似乎是此时发生的系统进程导致应用程序断断续续。活动监测仪器此时显示高峰,但我真的不知道如何解释数据/没有明显的突出显示。 (图像2)
系统使用工具在I / O活动跟踪中未显示任何活动。
文件活动工具似乎无法使用。
我的问题是:我应该如何调试此问题?我可以使用哪种乐器,以及如何使用?
确认其他人在此/其他硬件上看到此问题将会受到赞赏,以及对其原因/解决方案的建议。
由于
答案 0 :(得分:0)
如果您还没有,我建议您阅读Apple的Analyzing CPU Usage in Your App。如果这对您没有产生任何积极的结果,那么使用NSLog语句编写代码可能是另一种尝试查明涉及此问题的代码部分的方法。
请记住,由于CPU速度较快,您可能没有看到iPhone 6+的断断续续。 iPad 2有点陈旧,运行速度慢得多。这本身就是您问题的一个小线索。