来自调试器的 Ios Xcode 消息:由于内存问题而终止
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34089385/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Ios Xcode Message from debugger: Terminated due to memory issue
提问by Amalo
I have an app with collection view and a cell within this collection view that redirects to external link.
我有一个带有集合视图的应用程序和一个在这个集合视图中重定向到外部链接的单元格。
Whenever that link opens the app crashs in the background and gives on the debugger:
每当该链接打开时,应用程序就会在后台崩溃并在调试器上显示:
"Terminated due to memory issue".
“由于内存问题而终止”。
If I just press home button the app continues working just fine.
如果我只是按主页按钮,应用程序会继续正常工作。
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;
}
}
}
回答by jrturton
What device is this happening on? Once your app is in the background you can expect for it to be killed at any time - it doesn't have to be using excessive memory.
这是在什么设备上发生的?一旦您的应用程序进入后台,您就可以期待它随时被终止——它不必使用过多的内存。
If the new foreground app wants more memory, the OS will give it as much as it can. It will send a memory warning to any backgrounded apps. If they don't respond by reducing the memory footprint, or the foreground app still wants more memory, then the background apps are killed.
如果新的前台应用程序需要更多内存,操作系统会尽可能多地提供。它将向任何后台应用程序发送内存警告。如果它们没有通过减少内存占用来响应,或者前台应用程序仍然需要更多内存,那么后台应用程序就会被杀死。
Your app isn't crashing, it is being killed by the OS because it is no longer the foreground app and its resources are needed elsewhere.
您的应用程序没有崩溃,而是被操作系统杀死,因为它不再是前台应用程序,并且其他地方需要它的资源。
回答by nullLululi
I have the same problem - terminated due to memory issue when the memory usage still low.
我有同样的问题 - 当内存使用率仍然很低时由于内存问题而终止。
Then I found the reason: actually the memory allocated very quickly.
然后我找到了原因:其实内存分配的很快。
Just because the memory was destroyed very quickly, so it seems memory usage is still very low. You can use instruments to see current memory usage / total memory usage picture to explain how view memory usage / total memory usageThe picture is found from internet, but explain the problem clearly. You will find this value in the rapid reduction, the the area of ??light color is quickly grow, then your app crash due to memory issue when memory usage still low.
只是因为内存销毁的很快,所以看起来内存使用率还是很低的。可以用instruments查看当前内存使用量/总内存使用量 图片来解释如何查看内存使用量/总内存使用量图片是从网上找到的,但要清楚地说明问题。你会发现这个值在快速减少,浅色区域快速增长,然后当内存使用率仍然很低时你的应用程序由于内存问题而崩溃。
回答by Tommie C.
I would check elsewhere in your code. The answer is more than likely that you have a retain cycle somewhere and are leaking memory. Search for items like closures where you may have neglected to declare self as weak (may be nil) or unowned (never nil in that instance but that self is not owned by the closure object)
我会检查您代码中的其他地方。答案很可能是您在某处有一个保留周期并且正在泄漏内存。搜索闭包之类的项目,您可能忽略了将 self 声明为弱(可能为零)或无主(在这种情况下永远不会为零,但该 self 不属于闭包对象)
[weak self]
or
或者
[unowned self]
Instruments can help you but a detailed inspection of the objects in use (controllers, custom view classes, custom tableviewcell subclasses, tableviewrowaction delegate methods that might reference self, etc.) will be required. When you find the suspect area and make corrections, you should test the behavior on your device and see if you can spot the leak in instruments.
Instruments 可以帮助您,但需要对正在使用的对象(控制器、自定义视图类、自定义 tableviewcell 子类、可能引用 self 的 tableviewrowaction 委托方法等)进行详细检查。当您找到可疑区域并进行更正时,您应该测试设备上的行为,看看是否可以发现仪器中的泄漏。
Verify that your fix removes the leak, test more and verify that no other leaks are happening (most likely it's more than one).
确认您的修复消除了泄漏,进行更多测试并确认没有发生其他泄漏(很可能不止一次)。