Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Richard Birkett

macrumors member
Original poster
Aug 21, 2011
30
0
Hi,

I get EXC BAD ACCESS on the the first line in move: which mentions snakeArray, an NSMutableArray, I don't have a clue what's going on. Help much appreciated.
Code:
//in header:
	NSMutableArray *snakeArray;
//in imp.:

- (IBAction)start:(id)sender
{
	NSLog(@"1");
	snakeArray = [NSMutableArray arrayWithObject:[NSValue valueWithRect:NSMakeRect(truncf(gridSize*gridWidth/2)+gridSpacing/2, truncf(gridSize*gridHeight/2)+gridSpacing/2, squareSize, squareSize)]];
	theTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(move:) userInfo:nil repeats:YES];
	NSLog(@"2");
}

- (void)move:(NSTimer *)myTimer
{
	NSLog(@"3%@", snakeArray); //happens here with the snake array, otherwise after "3" just below
		//NSPoint lastSquare = [[snakeArray lastObject] rectValue].origin;
	NSValue *lastSquare = [snakeArray lastObject];
	NSLog(@"4");
	NSPoint lastSquarePoint = [lastSquare rectValue].origin;
 
So snakeArray is not a property?

I very much recommend a programming style where you give class member variables a slightly different name, like snakeArray_ , so that all accesses stand out.

And you shouldn't have many accesses. You should declare a "retain" property named "snakeArray" and use that; that way you take care of memory handling except for an assignment snakeArray = nil in your dealloc method.

The crash that you have isn't really random but inevitable since the array is autoreleased.
 
I think the problem that is you're having is with how you're creating your NSMutableArray. If you create your array with init then it is created with a retain count of 1. If you use one of the convenience methods (arrayWithObject in this case) then the object is autoreleased (released at the end of the current sequential code execution). You are using a convenience method so your NSMutableArray will be released at the end of start unless you retain it yourself (not recommended) or as gnasher729 said, you use a property that will automatically retain it for you.
 
Thanks!

Very helpful. Perhaps you could possibly help me with a small unrelated error to avoid clogging up this forum. :)

I have this code:

Code:
- (void)move:(NSTimer *)myTimer
{
	NSPoint lastSquare = [[snakeArray lastObject] rectValue].origin;
	switch (nextDirection) {
		case moveUp:
		{
			CGRect newSquare = NSMakeRect(lastSquare.x, lastSquare.y+gridSize, squareSize, squareSize);
			break;
		}
		case moveDown:
		{
			CGRect newSquare = NSMakeRect(lastSquare.x, lastSquare.y-gridSize, squareSize, squareSize);
			break;
		}
		case moveRight:
		{
			CGRect newSquare = NSMakeRect(lastSquare.x+gridSize, lastSquare.y, squareSize, squareSize);
			break;
		}
		case moveLeft:
		{
			CGRect newSquare = NSMakeRect(lastSquare.x-gridSize, lastSquare.y, squareSize, squareSize);
			break;
		}
	}
	[snakeArray addObject:[NSValue valueWithRect:newSquare]];
	currentDirection = nextDirection;
	[self setNeedsDisplay:YES];
}

Firstly you'll notice the {} after each case, for some reason, it wouldn't accept the declaration, then break but had been accepting a message and then break :S... but now it error saying newSquare is an undeclared identifier after the switch!!!
 
Declare newSquare once before the switch. Assign to it inside your cases. The {} in a case is odd and unnecessary.

-Lee
 
Declare newSquare once before the switch. Assign to it inside your cases. The {} in a case is odd and unnecessary.

-Lee

The error was that he was redeclaring newSquare repeatedly within the same scope (in each case statement). Scoping newSquare in the case statements made that error go away but took newSquare out of scope of the enclosing method. Personally, I prefer to declare everything at the very beginning of a method or function, this scattering of declarations throughout code looks sloppy and wrong. (I also like to order my declarations by size, to possibly conserve stack space, but that is just me being AR.)
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.