【问题标题】:Memory Leak Warnings, Due To NSArray Of Large Images内存泄漏警告,由于 NSArray 的大图像
【发布时间】:2011-06-10 15:09:45
【问题描述】:

我有一个 iPad 应用程序,它是儿童读物。您通过调用此操作从一个页面导航到下一个页面,该操作本质上淡出当前页面并淡入下一页,然后用 NSArray 的下一行填充三个堆栈 UIImageViews,因此它准备完成该操作下一页:

-(void)delayedMethod{

    [leftButton setAlpha:1];

    [pageImageNext setAlpha:0];
    [pageImage setAlpha:1];
    [pageImageBack setAlpha:1];

    NSString *imageExtension = @".jpg";
    NSString *audioExtension = @".wav";

    if (activePage == thePages.count/3)
    {
        activePage = 1;
    }
    else 
    {
        activePage = activePage + 1;
    }

    NSInteger row = 0;
    if(activePage == 0)
    {
        row = activePage;
    }
    else
    {
        row = ((activePage) * 3);
    }   

    [leftButton setAlpha:1];

    pageImageBack.image = [UIImage imageNamed:[NSString stringWithFormat:@"%@%@", [thePages objectAtIndex:row+0], imageExtension]];
    pageImage.image = [UIImage imageNamed:[NSString stringWithFormat:@"%@%@", [thePages objectAtIndex:row+1], imageExtension]];
    pageImageNext.image = [UIImage imageNamed:[NSString stringWithFormat:@"%@%@", [thePages objectAtIndex:row+2], imageExtension]];

    [UIImageView beginAnimations:NULL context:NULL];
    [UIImageView setAnimationDuration:.5]; // you can set this to whatever you like
    /* put animations to be executed here, for example: */

    [leftButton setAlpha:0];
    [rightButton setAlpha:0];
    [leftButton setAlpha:1];
    [rightButton setAlpha:1];
    leftButton.hidden = NO;


    /* end animations to be executed */
    [UIImageView commitAnimations]; // execute the animations listed above

    [imageExtension release];


}

NSArray在这个action中被加载,在ViewDidLoad中被调用:

-(void)loadPages
{
    thePages = [[NSArray alloc] initWithObjects:
                   //   How many stacked images do we need to get fade in and outs? Also add column fo
                @"page0",@"page0",@"page1",
                @"page0",@"page1",@"page2",
                @"page1",@"page2",@"page3",
                @"page2",@"page3",@"page4",
                @"page3",@"page4",@"page5",
                @"page4",@"page5",@"page6",
                @"page5",@"page6",@"page7",
                @"page6",@"page7",@"page8",
                @"page7",@"page8",@"page9",
                @"page8",@"page9",@"page10",
                @"page9",@"page10",@"page11",
                @"page10",@"page11",@"page12",
                @"page11",@"page12",@"page13",
                @"page12",@"page13",@"page14",
                @"page13",@"page14",@"page15",
                @"page14",@"page15",@"page16",
                @"page15",@"page16",@"page17",
                @"page16",@"page17",@"page18",
                @"page17",@"page18",@"page19",
                @"page18",@"page19",@"page20",
                @"page19",@"page20",@"page21",
                @"page20",@"page21",@"page22",
                @"page21",@"page22",@"page23",
                @"page22",@"page23",@"page24",
                @"page23",@"page24",@"page25",
                @"page24",@"page25",@"page26",
                @"page25",@"page26",@"page27",
                @"page26",@"page27",@"page27",
                nil];

}

直到大约 10-12 页,当我开始在控制台中收到内存警告并且通常会崩溃时,一切都可以正常工作。

我很确定这只是在正确的时间发布三个大型 UIImageViews 的问题,但我不知道什么时候......我在代码中尝试了许多不同的地方。

【问题讨论】:

    标签: iphone objective-c ipad memory-leaks crash


    【解决方案1】:

    我正在做一个这样的应用程序,其中有很多用户可以更改的图像视图和标签。我一直收到警告和崩溃。唯一似乎可以解决这一切的事情就是让它们成为所有属性。我想在某个观点上坚持的一切,我都必须建立一个财产。这很好地处理了它,否则操作系统似乎吓坏了我必须分配很多东西,并且会发送内存警告,这会释放东西,然后当应用程序尝试访问它们时它会崩溃。看看你的 pageImageNext、pageImage、pageImageBack 属性是否有效。

    【讨论】:

    • 嗨 Sasquatch,我相信我已将 UIImageViews 设置为 h 文件中的属性。三个主要 UIImageView 中的每一个都声明为:@property (nonatomic,retain) IBOutlet UIImageView *pageImage;这就是“使它们成为所有属性”的全部意思吗?非常感谢任何其他帮助。谢谢!
    • @MishieMoo @zneak @YuzaKen 谢谢你们的想法,我实现了它们(或已经实现了),尽管我仍然遇到崩溃。我添加了更多信息,如果您可以再次查看该主题,看看是否有其他建议。
    • @Gabe 我猜您也想将else { row = ((activePage) * 3); } 更改为else { row = ((activePage) + 3); } 这就是我的意思是让它们成为属性,当您发布这些属性时?它应该在 dealloc 中,看起来像 self.pageImage = nil;
    【解决方案2】:

    确保您在视图控制器的dealloc 方法中执行[thePages release]];。不释放肯定会导致内存问题。

    您是否还在视图控制器中设置了 imageviews 保留属性?如果是这样,您还需要在dealloc 中发布它们。

    至于内存警告,您可以取消设置 didRecieveMemoryWarning 中的图像视图,然后只需添加检查以根据需要重新创建它们。

    【讨论】:

    • 感谢您的提示,我相信我的代码中包含所有这些项目,但它仍然给我带来了问题。我的 dealloc 是: - (void)dealloc { [pageImage release]; [pageImageBack 发布]; [pageImageNext 发布]; [页面发布]; [左键释放]; [右键释放]; [splashView 发布]; thePages = nil; [超级释放]; }
    • 在我的 .h 文件中,我列出了 UIImageViews,如下所示:@property (nonatomic,retain) IBOutlet UIImageView *pageImage; @property (nonatomic,retain) IBOutlet UIImageView *pageImageBack; @property (nonatomic,retain) IBOutlet UIImageView *pageImageNext;正如 Yazu 建议的那样,我还删除了图像扩展版本。到达第 9-15 行左右后仍然收到内存警告和崩溃......当我从一行移动到另一行时,我是否需要释放 UIImageViews,而不仅仅是在(void)dealloc 中?还是我需要在其他时间调用 (void) dealloc?
    • 另外,我似乎在控制台崩溃时收到此消息,我认为这表明存在内存问题:程序收到信号:“0”。数据格式化程序暂时不可用,将在“继续”后重试。 (加载共享库“/Developer/usr/lib/libXcodeDebuggerSupport.dylib”时出现未知错误)
    【解决方案3】:

    代码:

    [imageExtension release];
    

    不正确,应删除。 “imageExtension”在堆栈上分配,并在方法退出时消失。只释放你分配的东西。

    您是否只有其中一种类型的 ViewController?还是每页一个?

    【讨论】:

    • 它实际上是静态分配在程序的数据段中(一个独立于堆栈和堆的位置),释放它什么都不做。方法调用后它不会消失,你可以return @"foo" 任何你想要的,什么都不会崩溃。也就是说,“只释放你分配的东西”的建议是正确的,尽管你还需要释放你已经保留(显然)和复制的东西。
    • 我只有一个这样的视图控制器,它处理三个 UIImageViews 的所有 alpha 更改,以及更改每个 UIImageView 中包含的图像,因为它在 NSArray 上下移动。非常感谢任何其他帮助。谢谢!
    【解决方案4】:

    @sasquatch @YuzaKen @MishieMoo 如果我简单地设置 self.pageImage = nil;正如您所建议的那样,在 dealloc 中,这不会仅在用户离开 ViewController 时释放内存吗?

    当我用新图像替换 UIImageView 的内容时,当我向下移动数组的行时,我觉得我需要释放 UIImageViews,不是吗?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-23
      • 1970-01-01
      • 2011-09-03
      • 2021-12-27
      • 1970-01-01
      • 2011-10-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多