考虑以下图片:
我的应用程序首先找到所有蓝色像素,并记录所有兄弟姐妹的x,y坐标(给定像素的兄弟姐妹是那些边界的兄弟姐妹:上,下,左,右,左上,上 - 对等等)。然后它遍历所有这些蓝色像素,以便弄清楚他们有多少蓝色兄弟。目标是最终确定哪一组蓝色像素是最大的。
这是一个很大的循环,它最终导致错误“警告:无法恢复以前选择的帧”。我相信这是因为我在堆栈中溢出。如果是这种情况,您会如何建议我更改我的代码以解决此问题?
以下是代码:
开始循环的方法:
for (NSString *key in pixelItemDict) {
Pixel *px = [pixelItemDict objectForKey:key];
if (!px.hasBeenCounted) {
//If it hasn't been counted, we know that we're onto a new distinct area, because otherwise counterForSiblingsOfPixel would have already counted it. So we now add a copy of the pixelsCurrentlyBeingCounted array, empty that array, and reset the counter
[pixelCounterDict setObject:[pixelsCurrentlyBeingCounted copy] forKey:[NSString stringWithFormat:@"%i",currentPxCounter]];
[pixelsCurrentlyBeingCounted removeAllObjects];
[self counterForSiblingsOfPixel:px];
}
}
连续调用自身的方法,导致堆栈溢出:
- (void)counterForSiblingsOfPixel:(Pixel *)px
{
[pixelsCurrentlyBeingCounted addObject:px];
currentPxCounter++;
px.hasBeenCounted = true;
for (Pixel *sibling in px.siblings) {
if (!sibling.hasBeenCounted) [self counterForSiblingsOfPixel:px];
}
}
基本上,我有一个包含所有蓝色像素的pixelItemDict
。我枚举这个字典,在每个字典上调用方法counterForSiblingsOfPixel:
。该方法依次调用传递给它的像素的每个兄弟姐妹。 forin
循环仅在蓝色区域中的每个像素都被计数后才重新获得控制权。因此,大面积的蓝色会导致counterForSiblingsOfPixel:
调用自身很多次,导致溢出。
在这种情况下是否应该使用标准设计模式?
答案 0 :(得分:4)
首先,您不是要修改px
,因此每次调用-counterForSiblingsOfPixel:
都会做同样的事情。当您使用递归时,您希望确保每个递归级别在某种程度上简化了问题。如果递归最终没有达到某种基本情况,它将永远继续下去,是的,溢出堆栈。因此,首先要确保您对该方法的调用是针对某些更简单的情况。
其次,您可能不希望仅通过一个像素进行简化...如果此方法将像素分成两半并且每半次递归调用自身,那就没问题了,因为您最终只会log2(像素)递归级别 - 大约20个百万像素。但是如果你处理一个像素然后递归调用剩下的像素,你最终会得到1000000级递归,这也会溢出。