IOS:由于可能使用了大量内存导致项目崩溃(使用ARC但可能是由于图像大小)

时间:2013-03-26 16:43:40

标签: ios objective-c memory

嘿,我的应用程序遇到了一些问题。这是我对IOS的第一个大项目,到目前为止我一直做得非常好,有些部分在这里和那里都很困扰。但是现在发展基本上已经结束了,我遇到了最大的问题,一直困扰着我,而且我遇到了障碍。我不知道该怎么办(我有一个想法,但不确定这是否有效)。在我的电脑上,它大部分时间都有效。有时它 崩溃,我收到一个错误(见下文)。当我收到错误时我所做的通常是游戏正在运行然后突然停止。实际上我有一段时间没有收到错误,而且我在开发过程中大部分都得到了它。 当应用程序在我的老板机器或实际设备上运行时(注意我们将应用程序从她的机器上传到设备而不是从我的机器上),它会崩溃。它总是在同一点崩溃。出现第一个视图,标题屏幕。然后,他们单击开始按钮,然后启动新视图。但是,他们单击开始按钮,应用程序最终崩溃。应用程序关闭并且调试器转到代码的这一部分会发生什么。

int main(int argc, char *argv[])
{
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([MyAppDelegate class]));
    }
}

此外,该应用程序是一个游戏。所有视图都使用OpengelEs。 我在想的是,正在使用大量内存。游戏正在运行;系统需要更多内存,系统会杀死一个释放内存的进程;该过程是应用程序。这是基于我对IOS和应用程序生命周期的了解。我正在使用ARC,但我已经使用他们的工具测试了很多游戏,我没有发现任何可能导致问题的内存泄漏或类似事情。我认为图像可能是大文件大小。图像范围从100kb到5 MB。我们正在缩小尺寸,但我不确定这是不是问题。现在,我遇到崩溃的唯一原因就是内存耗尽,我找到的唯一原因是文件大小。我不是100%确定这是原因,因为它不能解释为什么它不会在我的机器上崩溃(至少不是最近)但它​​确实在她身上(它解释了为什么它对她的机器和设备有效并且它解释了为什么它有时会发生在我的身上,而不是它们发生在不同的条件下)。此外,我一直听说在发生这种情况时应该发生某种类型的低内存警告。有人可以确认否认这一点(我已经研究了这个,但没有发现很多

所以我要问的是,是否有人可能对此问题的原因有任何更多的建议,或者至少引导我进入我应该研究更多的主题。您认为降低图像的文件大小是否有效。往往有1个背景约为1-3,然后是8到40个100kb的图像。

修改 我使用了配置文件模式。该应用程序开始使用100mb,然后播放时达到500mb(这是在实际内存中)。我注意到,当我切换到一个新的水平时,它只会增加内存。我想这是因为每个级别都有更多的图像显示,但后来我做了一个测试。在测试中,而不是在级别完成时进入下一级别,再次播放一级。 每个级别都是Class Level的对象。我的ViewControler(它是GLKViewController的子类)有一个名为currentLevel的属性。游戏使用以下代码切换到下一个级别:

-(void) nextLevel: (Level) newLevel
{
    //play sound
    MyAppDelage *del=[[UIApplication sharedApplication] delegate];
    UIWindow *main=[delegate window];
    MyViewControler *view=(MyViewControler*) main.rootViewController;
    view.currentLevel=newLevel;
 }

所以我认为正在发生的事情是,由于某些原因,旧级别从未被垃圾收集;如果有任何不同,currentLevel是强大的。 我也有 @synthesize currentLevel = _currentLevel; 这是我第一次学习Objective C时编写的旧代码。我只是按照示例进行操作。可能改变强类型或删除@synthesize部分会有助于解决这个问题吗? 我使用更多的C ++ / C#/ Java语法,所以我真的不习惯一些客观的C风格。

1 个答案:

答案 0 :(得分:6)

如果没有看到您的任何代码,我建议您查看以下内容:

  1. 检查您使用的图像是否具有较小的像素尺寸,因为Apple建议宽度/高度大于1024像素的图像最好分割成图块。以Apple的PhotoScroller.app代码为例。请注意,虽然图像的大小可能很小(例如100 kb),但为了显示它,iOS需要使用每像素4个字节对其进行解码!因此,3000x3000像素的图像使用3000x3000 * 4 = 36,000,000字节,相当于大约34 MB的内存。
  2. 虽然您正在使用ARC,但请查看代码中的/ while循环,这些循环可以使用@autoreleasepool {..}处理图像和环绕(如果适用)图像处理代码。例如:

    for (NSString *imageName in imageNames) {
        @autoreleasepool {
            //... code here to get your images for display ...
        }
    }
    
  3. 仔细研究如何处理检索大量图像,即iOS缓存使用“imageNamed”和“imageWithContentsOfFile”获取的图像。该技术特别用于使用CATiledLayers处理大图像。以下代码片段显示了获取图像的两种方式:

    // The fetched image is cached by iOS when using:
    UIImage *image1 = [UIImage imageNamed:@"myimagename.png"];
    // You can control memory usage and freeing of the image when using:
    UIImage *image2 = [UIImage imageWithContentsOfFile:@"myPath/myimagename.png
    
  4. 您还可以查看Apple的LargeImageDownsizing示例中使用的代码,但请注意,在处理PNG文件时,这对我不起作用。我向Apple提交了一份错误报告(去年11月),但还没有听到任何消息。

  5. 最后不要等待太长时间在真实设备上进行测试,因为您的开发Mac至少比目标iDevice快10倍,并且在您开始注意到内存相关问题之前还有更多可用内存。通过使用Instruments.app来分析您的应用程序,这总是一个好习惯。

  6. 希望以上建议可以帮到你!仅仅是我的2欧元美分,还有它的价值。