在我的Objective-C应用程序中,我在构建wordsearch应用程序时收到 EXC_BAD_ACCESS 错误(代码= 2),并且在我的项目中使用ARC - 但我无法解决问题 - 这可能是是由于堆栈溢出?
下面的代码指的是一个wordsearch测试算法 - 它用随机坐标扫描每个单词,以测试它是否适合给定的方向。如果不能,则选择另一个随机坐标点并再次尝试。经过一定程度的尝试后,如果它不适合其中的单词,则扫描每个坐标点以便拟合。如果这不起作用 - 我拿出wordsearch并从头开始。
此代码可以解决问题。如果算法在大约1,000次尝试中找到有效的单词搜索,那么它将按预期进行。大约1,000(每次都不同)后 - 它与 EXC_BAD_ACCESS 崩溃。我测试了泄漏和僵尸没有成功。
堆栈跟踪和错误消息是这样的(违规行并不总是相同......)
http://i57.tinypic.com/68x9vo.png.png
代码是(这看起来很长,但实际上只是8个可能事件的if语句,并且在整个过程中编码相似):
此方法根据其坐标和方向查看单词是否适合网格:
- (void)checkWordToSearch:(NSString *)word rvalueToPick:(int)rvalue svalueToPick:(int)svalue
{
BOOL picked = FALSE;
BOOL isthereaconflict = FALSE;
NSString *theWord = word;
int r = rvalue;
int s = svalue;
for (int i = 0; i < [self.randomDirectionArray count]; i++)
{
{
if (picked == FALSE)
{
if ([[self.randomDirectionArray objectAtIndex:i]isEqualToString:@"1"]&&isthereaconflict == FALSE)
{
if ((r+1)>=[theWord length])
{
// NSLog(@"-1-");
for (int z = 0; z < [theWord length]; z++)
{
if ([[[self.arrayOfArrays objectAtIndex:r-z]objectAtIndex:s]isEqualToString:@""] || [[[self.arrayOfArrays objectAtIndex:r-z]objectAtIndex:s]isEqualToString:@"-"]||[[[self.arrayOfArrays objectAtIndex:r-z]objectAtIndex:s]isEqualToString:[theWord substringWithRange:NSMakeRange(z,1)]])
{
}
else {
isthereaconflict = TRUE;
}
}
if (isthereaconflict == FALSE)
{
_direction = 1;
_correctr = r;
_verticals++;
_corrects = s;
picked = TRUE;
_numberOfTries = 0;
if (_emergencyStart == TRUE)
{
_emergencyEnd = TRUE;
}
}
}
else
{
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// GOING DOWN
else if ([[self.randomDirectionArray objectAtIndex:i]isEqualToString:@"5"]&&isthereaconflict == FALSE)
{
if ((r+[theWord length])<=11)
{
for (int z = 0; z < [theWord length]; z++)
{
if ([[[self.arrayOfArrays objectAtIndex:r+z]objectAtIndex:s]isEqualToString:@""] || [[[self.arrayOfArrays objectAtIndex:r+z]objectAtIndex:s]isEqualToString:@"-"]||[[[self.arrayOfArrays objectAtIndex:r+z]objectAtIndex:s]isEqualToString:[theWord substringWithRange:NSMakeRange(z,1)]])
{
}
else {
isthereaconflict = TRUE;
}
}
if (isthereaconflict == FALSE)
{
_direction = 5;
_verticals++;
_correctr = r;
_corrects = s;
picked = TRUE;
_numberOfTries = 0;
if (_emergencyStart ==TRUE)
{
_emergencyEnd = TRUE;
}
}
}
else
{
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// GOING RIGHT
else if ([[self.randomDirectionArray objectAtIndex:i]isEqualToString:@"3"]&&isthereaconflict == FALSE)
{
if ((s+[theWord length])<=11)
{
for (int z = 0; z < [theWord length]; z++)
{
if ([[[self.arrayOfArrays objectAtIndex:r]objectAtIndex:s+z]isEqualToString:@""] ||[[[self.arrayOfArrays objectAtIndex:r]objectAtIndex:s+z]isEqualToString:@"-"]|| [[[self.arrayOfArrays objectAtIndex:r]objectAtIndex:s+z]isEqualToString:[theWord substringWithRange:NSMakeRange(z,1)]])
{
}
else {
isthereaconflict = TRUE;
}
}
if (isthereaconflict == FALSE)
{
// NSLog(@"Correct 3");
_direction = 3;
_horizontals++;
_correctr = r;
_corrects = s;
_numberOfTries = 0;
picked = TRUE;
if (_emergencyStart ==TRUE)
{
_emergencyEnd = TRUE;
}
}
}
else
{
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// GOING LEFT
else if ([[self.randomDirectionArray objectAtIndex:i]isEqualToString:@"7"]&&isthereaconflict == FALSE)
{
if ((s-1)>=0 && (s-1)>=[theWord length])
{
for (int z = 0; z < [theWord length]; z++)
{
if ([[[self.arrayOfArrays objectAtIndex:r]objectAtIndex:s-z]isEqualToString:@""] ||[[[self.arrayOfArrays objectAtIndex:r]objectAtIndex:s-z]isEqualToString:@"-"]|| [[[self.arrayOfArrays objectAtIndex:r]objectAtIndex:s-z]isEqualToString:[theWord substringWithRange:NSMakeRange(z,1)]])
{
}
else {
isthereaconflict = TRUE;
}
}
if (isthereaconflict == FALSE)
{
_direction = 7;
_horizontals++;
_correctr = r;
_corrects = s;
_numberOfTries = 0;
picked = TRUE;
if (_emergencyStart ==TRUE)
{
_emergencyEnd = TRUE;
}
}
}
else
{
}
}
else if ([[self.randomDirectionArray objectAtIndex:i]isEqualToString:@"2"]&&isthereaconflict == FALSE)
{
//NSLog(@"GOING RIGHT UP");
if ((r+1)>=[theWord length] && (s+[theWord length])<=11)
{
for (int z = 0; z < [theWord length]; z++)
{
if ([[[self.arrayOfArrays objectAtIndex:r-z]objectAtIndex:s+z]isEqualToString:@""] ||[[[self.arrayOfArrays objectAtIndex:r-z]objectAtIndex:s+z]isEqualToString:@"-"]|| [[[self.arrayOfArrays objectAtIndex:r-z]objectAtIndex:s+z]isEqualToString:[theWord substringWithRange:NSMakeRange(z,1)]])
{
}
else {
isthereaconflict = TRUE;
}
}
if (isthereaconflict == FALSE)
{
_direction = 2;
_backdiagonals++;
_correctr = r;
_corrects = s;
picked = TRUE;
_numberOfTries = 0;
if (_emergencyStart ==TRUE)
{
_emergencyEnd = TRUE;
}
}
}
else
{
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// GOING LEFT AND UP
else if ([[self.randomDirectionArray objectAtIndex:i]isEqualToString:@"8"]&&isthereaconflict == FALSE)
{
if ((r+1)>=[theWord length] && (s-1)>=[theWord length] && (s-1)>=0)
{
for (int z = 0; z < [theWord length]; z++)
{
if ([[[self.arrayOfArrays objectAtIndex:r-z]objectAtIndex:s-z]isEqualToString:@""] ||[[[self.arrayOfArrays objectAtIndex:r-z]objectAtIndex:s-z]isEqualToString:@"-"]|| [[[self.arrayOfArrays objectAtIndex:r-z]objectAtIndex:s-z]isEqualToString:[theWord substringWithRange:NSMakeRange(z,1)]])
{
}
else {
isthereaconflict = TRUE;
}
}
if (isthereaconflict == FALSE)
{
_direction = 8;
_diagonals++;
_correctr = r;
_corrects = s;
picked = TRUE;
_numberOfTries = 0;
if (_emergencyStart ==TRUE)
{
_emergencyEnd = TRUE;
}
}
}
else
{
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// GOING RIGHT AND DOWN
else if ([[self.randomDirectionArray objectAtIndex:i]isEqualToString:@"4"]&&isthereaconflict == FALSE)
{
if ((s+[theWord length])<=11 && (r+[theWord length])<=11)
{
for (int z = 0; z < [theWord length]; z++)
{
if ([[[self.arrayOfArrays objectAtIndex:r+z]objectAtIndex:s+z]isEqualToString:@""] ||[[[self.arrayOfArrays objectAtIndex:r+z]objectAtIndex:s+z]isEqualToString:@"-"]|| [[[self.arrayOfArrays objectAtIndex:r+z]objectAtIndex:s+z]isEqualToString:[theWord substringWithRange:NSMakeRange(z,1)]])
{
}
else {
isthereaconflict = TRUE;
}
}
if (isthereaconflict == FALSE)
{
_direction = 4;
_diagonals++;
_correctr = r;
_corrects = s;
picked = TRUE;
_numberOfTries = 0;
if (_emergencyStart ==TRUE)
{
_emergencyEnd = TRUE;
}
}
}
else
{
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// GOING LEFT AND DOWN
else if ([[self.randomDirectionArray objectAtIndex:i]isEqualToString:@"6"]&&isthereaconflict == FALSE)
{
if ((s-1)>=[theWord length] && (r+[theWord length])<=11&&(s-1)>=0)
{
for (int z = 0; z < [theWord length]; z++)
{
//NSString *theString = [theWord substringWithRange:NSMakeRange(z,1)];
if ([[[self.arrayOfArrays objectAtIndex:r+z]objectAtIndex:s-z]isEqualToString:@""] || [[[self.arrayOfArrays objectAtIndex:r+z]objectAtIndex:s-z]isEqualToString:@"-"]||[[[self.arrayOfArrays objectAtIndex:r+z]objectAtIndex:s-z]isEqualToString:[theWord substringWithRange:NSMakeRange(z,1)]])
{
}
else {
isthereaconflict = TRUE;
}
}
if (isthereaconflict == FALSE)
{
_backdiagonals++;
_direction = 6;
_correctr = r;
_corrects = s;
_numberOfTries = 0;
picked = TRUE;
if (_emergencyStart ==TRUE)
{
_emergencyEnd = TRUE;
}
}
}
else
{
}
}
}
}
}
if (picked == FALSE)
{
_numberOfTries ++;
if (_numberOfTries > 500 && _emergencyStart == FALSE)
{
_problemSorted = FALSE;
[self emergencyCheck:theWord];
}
else if (_emergencyStart == TRUE)
{
}
else
{
[self gameWithWord:theWord];
}
}
else{
//NSLog(@"NO CONFLICT");
if (_emergencyEnd == TRUE)
{
_problemSorted = TRUE;
}
//NSLog(@"Final: theWord: %@, rvalue: %d, svalue: %d, direction: %d", theWord, rvalue, svalue, _direction);
_numberOfTries = 0;
_emergencyEnd = FALSE;
_emergencyStart = FALSE;
[self addWordToSearch:theWord theWord2:rvalue thervalue:svalue thesvalue:_direction];
}
}
它所指的随机方向数组是:
- (void)createRandomDirectionArray
{
if (_horizontals < 4)
{
//NSLog(@"-H");
[_anArray addObject:@"3"];
[_anArray addObject:@"7"];
}
if (_verticals < 4)
{
//NSLog(@"-V");
[_anArray addObject:@"1"];
[_anArray addObject:@"5"];
}
if (_diagonals < 2)
{
//NSLog(@"-D");
[_anArray addObject:@"4"];
[_anArray addObject:@"8"];
}
if (_backdiagonals < 2)
{
//NSLog(@"-B");
[_anArray addObject:@"2"];
[_anArray addObject:@"6"];
}
[self.randomDirectionArray removeAllObjects];
for (int i = 0; i < [_anArray count]; i++)
{
int r = arc4random() % [_anArray count];
[self.randomDirectionArray addObject:[_anArray objectAtIndex:r]];
[_anArray removeObjectAtIndex:r];
}
for (int i = 0; i < [self.randomDirectionArray count]; i++)
{
//NSLog(@"Element %d: %d", i, [[self.randomDirectionArray objectAtIndex:i]intValue]);
}
}
gameWithWord方法是:
- (void)gameWithWord:(NSString *)theWord
{
[self randomCoordinates]; //GENERATES A PAIR OF RANDOM COORDINATES
[self createRandomDirectionArray];
_attempts ++;
[self checkWordToSearch:theWord rvalueToPick:_correctr svalueToPick:_corrects];
}
如果有人有任何想法会非常感激。
答案 0 :(得分:3)
似乎checkWordToSearch
正在调用gameWithWord
,但gameWithWord
似乎也会调用checkWordToSearch
。如果是这样,那种排序递归会导致你描述的行为(在看似随机的地方崩溃)。
我建议仔细检查逻辑,以确保它像你明显想要的那样退出递归循环。或者,更好的是,改变它,以便它不会递归地调用自己。如果你必须这样做而不回到runloop,你可以考虑在循环中使用自动释放块。