响应iOS中的RAM可用性

Mar*_*tos 9 textures opengl-es feature-detection ios

我有一个质量很重的OpenGL游戏,我想根据设备有多少RAM进行调整.最高分辨率的纹理我在iPhone 4或iPad2上运行良好,但早期的设备在加载纹理的过程中崩溃.我有这些纹理的低分辨率版本,但我需要知道何时使用它们.

我目前的策略是检测特定的旧设备(3GS有低分辨率屏幕; iPad没有摄像头),然后只加载IPad2及以上和iPhone 4及以上的高分辨率纹理 - 我想我需要为iPod touch做点事.但我更倾向于使用特征检测而不是硬编码设备模型,因为模型检测对于API和硬件的未来变化是脆弱的.

我正在考虑的另一种可能性是首先加载高分辨率纹理,然后在我得到低内存警告时丢弃并用lo-res替换它们.但是,我不确定我是否有机会回应; 我注意到应用程序经常在调试控制台上出现任何通知之前死掉.

如何检测我正在运行的设备是否有足够的RAM来加载我的纹理的高分辨率版本?

退后一步,是否还有一些我可以使用的自适应技术,这是特定于OpenGL纹理内存的?

笔记:

  1. 我搜索和关闭SO以获得与可用RAM检测相关的答案,但它们基本上都建议分析内存使用情况并消除浪费(最大限度地缩短临时工作的寿命,以及所有这些).我已经做了尽可能多的事情,而且我无法将高分辨率纹理压缩到旧设备中.

  2. PVRTC不是一种选择.纹理包含片段着色器要使用的数据,并且必须以无损格式存储.

Ste*_*eve 11

获取设备使用的总(最大)物理RAM [NSProcessInfo processInfo].physicalMemory.

文档.


Mar*_*tos 7

sysctl()本博客文章中所述,可以通过此处获得总物理RAM ,并在此处实现为一个很好的干净API (请参阅totalMemory相应的.m文件中的实现).

为了方便和后人,我提起了博客的代码:

#include <sys/sysctl.h>

size_t phys_mem()
{
 int mib[] = { CTL_HW, HW_PHYSMEM };
 size_t mem;
 size_t len = sizeof(mem);
 sysctl(mib, 2, &mem, &len, NULL, 0);
 return mem;
}
Run Code Online (Sandbox Code Playgroud)

我不知道Apple是否会批准sysctl()以这种方式使用的应用程序.它已记录在案,但仅适用于Mac OS X.

  • @Nate:是的.[Your World](http://itunes.apple.com/us/app/your-world/id412566625?mt=8)在超过384 MB的设备上加载9600万像素的地球; 否则,它会回落到2400万像素的版本.这个数字并没有什么特别之处; 它只是设备之间的一半,而那些不能. (2认同)
  • 只需使用[NSProcessInfo processInfo] .physicalMemory (2认同)