iOS Xcode调试器消息:由于内存问题终止。

5

我有一个带有集合视图的应用程序,其中包含一个单元格,该单元格将重定向到外部链接。

每当该链接打开时,应用程序会在后台崩溃,并在调试器上显示:

"由于内存问题终止"。

如果我只是按下主屏幕按钮,应用程序仍然可以正常工作。

if (UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation)) Portrait = NO;
else if (UIDeviceOrientationIsPortrait([UIDevice currentDevice].orientation)) Portrait = YES;
else Portrait = [self getStatusBarOrientations];

if(indexPath.row == 4 && indexPath.section == 0)
{
    NewsListCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell4"  forIndexPath:indexPath];

    if ([languageID isEqualToString:@"1025"])
    {
        cell.title.text =[NSString stringWithFormat:@"جريدة اليوم %@", [self.pdfCoverDict valueForKey:@"PdfDate"]];
        [cell.contentView setTransform:CGAffineTransformMakeScale(-1, 1)];
    } else {
        cell.title.text =[NSString stringWithFormat:@"Today's Edition %@", [self.pdfCoverDict valueForKey:@"PdfDate"]];
    }
    NSURL *imageUrl = [NSURL URLWithString:[self.pdfCoverDict valueForKey:@"CoverImage"]];
    [cell.imageView sd_setImageWithURL:imageUrl];
    cell.imageViewWidth.constant = Portrait ? 246 : 331;
    cell.imageViewHeight.constant = Portrait ? 350 : 471;
    return cell;

} else if(indexPath.row == 0) {
    NewsListCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"HeaderView" forIndexPath:indexPath];
    cell.title.text = [self.channelKeys objectAtIndex:indexPath.section];
    cell.backView.hidden = [channelID isEqualToString:@"1"] ? (indexPath.section == 0 ? YES : NO) : YES;
    if([languageID isEqualToString:@"1025"]) {
        [cell.contentView setTransform:CGAffineTransformMakeScale(-1, 1)];
    } else {
        [cell.contentView setTransform:CGAffineTransformMakeScale(-1, 1)];
        [cell.title setTransform:CGAffineTransformMakeScale(-1, 1)];
    }
    return cell;
} else {

    NSInteger row;
    if(indexPath.row != 1 && indexPath.row != 2 && indexPath.row != 3) {
        row = indexPath.row - 2;
    } else {
        row = indexPath.row - 1;
    }
    NSMutableArray * articles =  [self.channelArticles valueForKey:[self.channelKeys objectAtIndex:indexPath.section]];
     //        if(row < articles.count) {
    NSString *articleImage = [[articles objectAtIndex:row] valueForKey:@"ArticleMedia"];
    NSString *cellIdentifier;
    NSString *articleLangID = [NSString stringWithFormat:@"%@", [[articles objectAtIndex:row] valueForKey:@"LanguageID"]];

    if(indexPath.section == 0) {
        switch (indexPath.row)
        {
            case 1:
                if(![articleImage isEqualToString:@""]) cellIdentifier = @"Cell1";
                else cellIdentifier = @"CellNoImg";
                break;
            case 2:
                if(![articleImage isEqualToString:@""]) cellIdentifier = @"Cell2";
                else cellIdentifier = @"CellNoImg";
                break;
            case 3:
                if(![articleImage isEqualToString:@""]) cellIdentifier = @"Cell3";
                else cellIdentifier = @"CellNoImg";
                break;
            case 5:
                if(![articleImage isEqualToString:@""]) cellIdentifier = @"Cell5";
                else cellIdentifier = @"CellNoImg";
                break;
            case 6:
                if(![articleImage isEqualToString:@""]) cellIdentifier = @"Cell5";
                else cellIdentifier = @"CellNoImg";
                break;
            default:
                if(![articleImage isEqualToString:@""]) {
                    if([channelID isEqualToString:@"1"]) cellIdentifier = @"Cell6";
                    else cellIdentifier = @"Cell5";
                } else {
                    cellIdentifier = @"CellNoImg";
                }
                break;
        }
    } else {
        if(![articleImage isEqualToString:@""]) cellIdentifier = @"Cell5";
        else cellIdentifier = @"CellNoImg";
    }


    NewsListCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];

    if([[[articles objectAtIndex:row] valueForKey:@"LabelName"] isEqualToString:@""]) {
        cell.labelNameHeight.constant = 0;
    } else {
        cell.labelNameHeight.constant = 21;
    }
    cell.labelName.text = [[articles objectAtIndex:row] valueForKey:@"LabelName"];

    cell.title.text = [[articles objectAtIndex:row] valueForKey:@"MainHeadline"];

    if(indexPath.row == 3 && indexPath.section == 0) {
        if(![articleImage isEqualToString:@""]) cell.titleHeight.constant = [self lineCountForLabel:cell.title labelWidth:cell.frame.size.width - Portrait ? 254 : 337] * 35;
        else cell.titleHeight.constant = [self lineCountForLabel:cell.title labelWidth:cell.frame.size.width - 10] * 35;
    } else {
        cell.titleHeight.constant = [self lineCountForLabel:cell.title labelWidth:cell.frame.size.width - 10] * 35;
    }

    NSString *authorTime = [self getAuthorTime:[articles objectAtIndex:row]];
    if([authorTime isEqualToString:@""]) {
        cell.authorTimeHeight.constant = 0;
    } else {
        cell.authorTimeHeight.constant = 21;
    }
    cell.authorTime.text = authorTime;

    NSString *details = [[articles objectAtIndex:row] valueForKey:@"Introduction"];
    cell.details.attributedText = [self getAttributedString: details language: articleLangID];

    if([cellIdentifier isEqualToString:@"CellNoImg"]) {
        defaultLines = 5;
        if([cell.authorTime.text isEqualToString:@""]) defaultLines++;
        if([cell.labelName.text isEqualToString:@""]) defaultLines++;
        if(cell.titleHeight.constant / 35 == 1) defaultLines++;
        cell.details.numberOfLines = defaultLines;
    }

    if(indexPath.section == 0) {
        switch (indexPath.row)
        {
            case 2:
                cell.imageViewWidth.constant = Portrait ? 240 : 323;
                cell.imageViewHeight.constant = Portrait ? 151 : 199;
                break;
            case 3:
                cell.imageViewWidth.constant = Portrait ? 240 : 323;
                cell.imageViewHeight.constant = Portrait ? 151 : 199;
            case 5:
                cell.imageViewWidth.constant = Portrait ? 240 : 323;
                cell.imageViewHeight.constant = Portrait ? 151 : 199;
                break;
            case 6:
                cell.imageViewWidth.constant = Portrait ? 240 : 323;
                cell.imageViewHeight.constant = Portrait ? 151 : 199;
                break;
            default:
                cell.imageViewWidth.constant = Portrait ? 240 : 323;
                cell.imageViewHeight.constant = Portrait ? 151 : 199;
                break;
        }
    } else {
        cell.imageViewWidth.constant = Portrait ? 240 : 323;
        cell.imageViewHeight.constant = Portrait ? 151 : 199;
    }

    if (![articleImage isEqualToString:@""]) {
        NSURL *imageUrl = [NSURL URLWithString:articleImage];
        [cell.imageView sd_setImageWithURL:imageUrl];

    } else {
        [cell.imageView sd_setImageWithURL:nil];
    }

    if([articleLangID isEqualToString:@"1025"]) {
        [cell.contentView setTransform:CGAffineTransformMakeScale(-1, 1)];
        cell.labelName.textAlignment = NSTextAlignmentRight;
        cell.title.textAlignment = NSTextAlignmentRight;
        cell.authorTime.textAlignment = NSTextAlignmentRight;
        cell.details.textAlignment = NSTextAlignmentRight;
    } else {
        if (indexPath.row == 3) {
            [cell.contentView setTransform:CGAffineTransformMakeScale(-1, 1)];
            [cell.labelName setTransform:CGAffineTransformMakeScale(-1, 1)];
            [cell.title setTransform:CGAffineTransformMakeScale(-1, 1)];
            [cell.authorTime setTransform:CGAffineTransformMakeScale(-1, 1)];
            [cell.details setTransform:CGAffineTransformMakeScale(-1, 1)];
            [cell.imageView setTransform:CGAffineTransformMakeScale(-1, 1)];
        }
        cell.labelName.textAlignment = NSTextAlignmentLeft;
        cell.title.textAlignment = NSTextAlignmentLeft;
        cell.authorTime.textAlignment = NSTextAlignmentLeft;
        cell.details.textAlignment = NSTextAlignmentLeft;
    }
    return cell;

}

}


应用程序使用了多少内存?如果您使用Instruments运行,它将向您显示正在分配的内容。 - Phillip Mills
内存一直保持稳定,大约20MB左右,但仍然存在内存问题,尤其是在尝试滚动集合视图并直接点击链接时。 - Amalo
你没有重用集合视图单元吗? - Teja Nandamuri
你需要提供更多关于问题的细节。展示一下你如何重复使用单元格的代码。 - Teja Nandamuri
是的,我重复使用集合视图单元格。 - Amalo
4个回答

9
这是在哪个设备上发生的?一旦你的应用程序处于后台,它随时可能被终止 - 不必使用过多的内存。
如果新的前台应用程序需要更多内存,操作系统会尽可能地提供。它会向任何后台应用程序发送内存警告。如果它们没有通过减少内存占用来作出响应,或者前台应用程序仍然需要更多内存,则后台应用程序将被终止。
你的应用程序并没有崩溃,而是被操作系统终止,因为它不再是前台应用程序,其资源需要用于其他地方。

我正在使用iPad mini设备。 - Amalo

0
如果这个问题只在应用程序不活动时出现,那么它也可能是由测试设备上的其他(占用内存较多的)应用程序引起的。为了排除这种可能性,请禁用其他应用程序的后台应用刷新功能和/或关闭其他应用程序和/或重新启动设备。

0

我也遇到了相同的问题——尽管内存使用率仍然很低,但由于内存问题而终止。

后来我发现了原因:实际上内存分配非常快。

只是因为内存被快速销毁,所以看起来内存使用率仍然很低。您可以使用工具来查看当前内存使用情况/总内存使用情况(解释如何查看内存使用率/总内存使用率的图片)。虽然该图片来自互联网,但清楚地解释了问题。您将发现这个值在迅速减少,浅色区域迅速增长的时候,应用程序会由于内存问题而崩溃,即使内存使用率仍然很低。


0
我会检查你代码的其他地方。很可能答案是你在某个地方有一个保留循环并且正在泄漏内存。搜索像闭包这样的项目,你可能已经忽略了声明self为weak(可能为空)或unowned(在那种情况下永远不为空,但是self不是闭包对象所拥有的)。
[weak self]

或者

[unowned self]

工具可以帮助你,但需要对使用的对象进行详细检查(控制器、自定义视图类、自定义tableviewcell子类、可能引用self的tableviewrowaction委托方法等)。当您找到可疑区域并进行更正时,应在设备上测试行为,并查看是否可以在仪器中发现泄漏。

验证您的修复程序是否消除了泄漏,进行更多测试并验证是否没有其他泄漏发生(最有可能不止一个)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接