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

maplestar

macrumors member
Original poster
Oct 16, 2008
73
0
I read up on this error and it's supposedly thrown when I access a variable or object that has been released. But I'm not sure how to fix this error! I'm using Cocos2D to program a basic SpriteController that keeps track of all my Sprites and sends them a touchBegan: to keep track of touches.

I made a Basic HelloWorldScene.m that initializes like this:

-(id) init
{
if( (self=[super init] )) {

[SpriteController addSprite:[TouchBox touchBoxWithFile: @"red1.gif"]];
[[[SpriteController allMySprites] lastObject] setPosition: ccp(360, 180)];
[self addChild:[[SpriteController allMySprites] lastObject]];


[SpriteController addSprite:[TouchBox touchBoxWithFile: @"red1.gif"]];
[[[SpriteController allMySprites] lastObject] setPosition: ccp(120, 180)];
[self addChild:[[SpriteController allMySprites] lastObject]];


[[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self
priority:0
swallowsTouches:YES];
}
return self;
}

And then, when the Scene is touched, I pass it on to the SpriteController

- (BOOL) ccTouchBegan: (UITouch *)touch withEvent: (UIEvent *)event
{
CGPoint location = [[CCDirector sharedDirector] convertToGL: [touch locationInView: [touch view]]];

BOOL anyoneTouched = [SpriteController sendTouchBegan:location];

return anyoneTouched;
}

Finally, the SpriteController loops through all its Sprites, checks if they respond to touchBegan: and sends them the command.

+(BOOL) sendTouchBegan: (CGPoint) cgp
{
BOOL touched = FALSE;

if (allMySprites == nil) {
//touched = false;
} else {
for (CCSprite *sprite in allMySprites) {
if([sprite respondsToSelector:mad:selector(touchBegan: )]) {
touched = [sprite touchBegan: cgp];
}
}
}

return touched;
}

The program displays the 2 red1.gif boxes on the screen during initialization fine. And after debugging around, I figured that the flow of the program does enter the TouchBegan and is passed to the SpriteController. However, as soon as I begin looping through allMySprites, I get the EXC_BAD_ACCESS error. After playing around with it, I determined that I simply can't access any of the objects in allMySprites beyond initialization. So even if I added a [allMySprites lastObject] directly in the scene, it'd throw the error. Why can't I access the objects in allMySprites? They don't seem to be released by the time I want to use them, but it just doesn't let me touch them.

EDIT: Removed all the smiley's in my code :D
 
I think you need to read up the difference between a class and an object. You have a class, SpriteController, but you never actually instantiate it (that is, make an object of the class SpriteController).

The code you have posted doesn't show where allMySprites is defined, but I can hazard a guess at what's wrong. I bet you have made that an instance variable for SpriteController.

To make a new SpriteController you would do something like:

Code:
SpriteController* aController = [[SpriteController alloc] init];

Then, instead of [SpriteController addSprite: … ], you would do

Code:
[aController addSprite: … ]

That change is not in itself enough, as you would need some place to keep the SpriteController around. For that, you should make an instance variable (possibly with a property) in your HelloWorldScene to hold it.

Amorya

Amorya
 
I think you need to read up the difference between a class and an object. You have a class, SpriteController, but you never actually instantiate it (that is, make an object of the class SpriteController).

The code you have posted doesn't show where allMySprites is defined, but I can hazard a guess at what's wrong. I bet you have made that an instance variable for SpriteController.

To make a new SpriteController you would do something like:

Code:
SpriteController* aController = [[SpriteController alloc] init];

Then, instead of [SpriteController addSprite: … ], you would do

Code:
[aController addSprite: … ]

That change is not in itself enough, as you would need some place to keep the SpriteController around. For that, you should make an instance variable (possibly with a property) in your HelloWorldScene to hold it.

Amorya

Amorya

Sorry, I guess I didn't make myself completely clear. When I add a sprite in the initialization, the "addSprite:" method instantiates and creates the object in (don't have actual code, sorry) this manner:

allMySprites = [NSMutableArray array];

So it points to an mutable array object. allMySprites is a static NSMutableArray object, not an instantiation variable. So the addSprite method is a class method that adds to the allMySprite object, not to the specific SpriteController.
 
[I think this thread is in the wrong forum.]

"NSZombieEnabled" might help you pinpoint what object exactly is being accessed to cause the bad memory access:

Set an environment variable in Xcode: http://cocoa-nut.de/?p=16

or, using Instruments: http://www.markj.net/iphone-memory-debug-nszombie/

Really? This is development for my iPhone app, so I'm not sure where else to post this thread other than the iPhone app section.

Anyways, I know what object is being accessed which is causing the problem, but I'm not sure how to fix it. By playing around with the debugger and placing a few printf/NSLog's, I determined that the program always crashes when I try to access the objects inside allMySprites. I can access allMySprites just fine, but somehow, I'm not allowed to access the objects inside or call any methods with allMySprites.
 
Really? This is development for my iPhone app, so I'm not sure where else to post this thread other than the iPhone app section.

The "iPhone/iPad Programming" forum:

https://forums.macrumors.com/forums/135/

Anyways, I know what object is being accessed which is causing the problem, but I'm not sure how to fix it. By playing around with the debugger and placing a few printf/NSLog's, I determined that the program always crashes when I try to access the objects inside allMySprites. I can access allMySprites just fine, but somehow, I'm not allowed to access the objects inside or call any methods with allMySprites.

Enabling NSZombie in Instruments will stop the execution of the program at the crash and show you the retain/release history of the object you are accessing that is causing the crash. Something is causing the object to be over released.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.