I am developing a game for iOS with Obj-C and Apple's SpriteKit framework. My primary testing device is an iPad2 (model #MC773X/A running iOS8.1). My game runs smoothly on this device except for a single "stutter" around 60-120s in. At this time the app lags for around 150-300ms / 10-20 frames.
I have tested the same game app on an iPhone6+ (model #MGAJ2X/A running iOS8.4) which doesn't seem to have this problem.
I originally thought it had something to do with my game apps resource management, and then later maybe the debugging link itself... so I created the following testing app. It is simply a blank screen, that logs dt's above 20ms. It has an option to log to the screen (using SKLabelNodes) for testing without a debugging link.
This simple testing app shows the same stutter on the iPad2 without fail at around the 60s mark (built in debug/release, with/without debugging). The iPhone 6+ doesn't show the stuttering behaviour.
Starting with a new SpriteKit game template for iOS (I am using Xcode 6.4 but I saw the same bug with an earlier version - Xcode 6.something):
In GameViewController.m:
//scene.scaleMode = SKSceneScaleModeAspectFill;
scene.scaleMode = SKSceneScaleModeResizeFill;
Replace GameScene.m with:
#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
I am getting comfortable with using the time profiler instrument but in this case I don't think it is particularly helpful. It shows no activity for the duration of the stutter. (image1) (Unfortunately I'm a brand new poster so can't inline images)
It seems like it is a system process happening at this time which is causing the app to stutter. The activity monitor instrument shows a peak at this time but I don't really know how to interpret the data / nothing obvious stands out. (image2)
The system usage instrument shows no activity in the I/O activity track.
The file activity instrument doesn't seem to be available.
My question is: how should I approach debugging this issue? Which instrument could I use, and how?
Confirmation that others see this issue on this/other hardware would be appreciated as would suggestions to it's cause/resolution.
Thanks