SpriteKit SKTextureAtlas,由于加载纹理时的内存压力而终止

类似于WWDC的SpriteKit精选游戏“冒险”,我尝试通过拼贴加载我的背景图片。 我创build了一个包含6,300“瓦片”的纹理图集,每个瓦片的尺寸都是100×100像素。 完整的背景图像总共为30,000×2048(用于视网膜显示器)。 这个想法是,背景将从右侧移动到左侧(侧滚动)。 第一列和最后一列匹配,以便它们看起来连续。

当应用程序运行时,它将我的初始加载屏幕和标题图像加载到我的内存选项卡中的54MB ,CPU使用率为16% 。 这一直保持不变,我浏览菜单,直到我select我的关卡,它告诉后台线程加载关卡资产(其中包含前述的背景图片)。 整个.atlas文件夹显示只有35.4MB 。 我不相信这是一个问题,因为Adventure .atlas文件夹(来自WWDC)显示只有32.7MB

一旦我select了关卡,在我开始接收内存警告之前,它会在.atlas文件夹中加载大约20个纹理,并使应用程序崩溃。 我检查了仪器泄漏,并没有显示任何内存泄漏。 我没有收到任何编译器错误(甚至没有EXC_BAD_ACCESS之一)。 我查看过我的设备控制台,发现应用程序崩溃的地方有几行,但对我来说并不合适。 我也检查了僵尸,但似乎没有find任何。

CoreLevel.m

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ // Used to determine time spent to load NSDate *startDate = [NSDate date]; // Atlas to load SKTextureAtlas *tileAtlas = [SKTextureAtlas atlasNamed:@"Day"]; // Make sure the array is empty, before storing the tiles sBackgroundTiles = nil; sBackgroundTiles = [[NSMutableArray alloc] initWithCapacity:6300]; // For each row (21 Totals Rows) for (int y = 0; y < 21; y++) { // For each Column (100 Total Columns) for (int x = 1; x <= 100; x++) { // Get the tile number (0 * 32) + 0; int tileNumber = (y * 300) + x; // Create a SpriteNode of that tile SKSpriteNode *tileNode = [SKSpriteNode spriteNodeWithTexture:[tileAtlas textureNamed:[NSString stringWithFormat:@"tile_%d.png", tileNumber]]]; // Position the SpriteNode CGPoint position = CGPointMake((x * 100), (y * 100)); tileNode.position = position; // At layer tileNode.zPosition = -1.0f; tileNode.blendMode = SKBlendModeReplace; // Add to array [(NSMutableArray *)sBackgroundTiles addObject:tileNode]; } } NSLog(@"Loaded all world tiles in %f seconds", [[NSDate date] timeIntervalSinceDate:startDate]); }); 

这似乎是从debugging控制台的崩溃:

 com.apple.debugserver-300.2[9438] <Warning>: 1 +0.000000 sec [24de/1807]: error: ::read ( -1, 0x4069ec, 18446744069414585344 ) => -1 err = Bad file descriptor (0x00000009) com.apple.debugserver-300.2[9438] <Warning>: Exiting. com.apple.launchd[1] (UIKitApplication:tv.thebasement.Coin-Voyage[0x641d][9441]) <Notice>: (UIKitApplication:tv.thebasement.Coin-Voyage[0x641d]) Exited: Killed: 9 

我没有足够的声望发布图像,所以这里是一个链接到我的仪器的configuration截图的屏幕截图:

http://postimg.org/image/j17xl39et/

任何帮助和build议非常感谢! 如果我遗漏了一些相关的信息,我很高兴更新。

图像文件(PNG,JPG,地图集文件夹等)的文件大小告诉你什么关于内存使用情况。

相反,您必须使用以下公式计算纹理内存使用情况:

 width * height * (color bit depth / 8) = texture size in bytes 

例如,尺寸为4096×4096像素和32位颜色深度(4字节)的图像在加载为纹理(未压缩)时使用了这么多内存:

 4096 * 4096 * 4 = 67108864 bytes (64 Megabytes) 

根据您的规格(6,300个瓷砖,每个100×100像素,假设它们都是唯一的),您超出了纹理内存使用的任何合理限制(大约1.5千兆字节!)的方式,wayyyyyy。 考虑到35兆字节(对于阿特拉斯btw 巨大 )的图集大小,并假设只有10:1的压缩比,你可能仍然在看纹理内存使用量超过350兆字节。