Reputation: 15778
I got this error from XCode:
objc[8422]: FREED(id): message release sent to freed object=0x3b120c0
I googled and find that is related to the memory. But I don't know which line of code I go wrong, any ideas? After I launch my app in simulator, it prompts a second, than, no other error except the error above.
@implementation MyAppDelegate
@synthesize window;
@synthesize viewController;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// Override point for customization after app launch
[window addSubview:viewController.view];
[window makeKeyAndVisible];
[self changeScene:[MainGameMenuScene class]];
}
- (void)dealloc {
[viewController release];
[window release];
[super dealloc];
}
- (void) changeScene: (Class) scene
{
BOOL animateTransition = true;
if(animateTransition){
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:window cache:YES]; //does nothing without this line.
}
if( viewController.view != nil ) {
[viewController.view removeFromSuperview]; //remove view from window's subviews.
[viewController.view release]; //release gamestate
}
viewController.view = [[scene alloc] initWithFrame:CGRectMake(0, 0, IPHONE_WIDTH, IPHONE_HEIGHT) andManager:self];
//now set our view as visible
[window addSubview:viewController.view];
[window makeKeyAndVisible];
if(animateTransition){
[UIView commitAnimations];
}
}
Upvotes: 2
Views: 268
Reputation: 4335
[viewController.view release]; //release gamestate
That's an extra release (if you didn't alloc it, don't release it). A couple lines down:
viewController.view = [[scene alloc] initWithFrame:CGRectMake(0, 0, IPHONE_WIDTH, IPHONE_HEIGHT) andManager:self];
will release viewController.view again before retaining the new value, that will over-release the view and cause a crash (it sends the release message to an object that has already been dealloc'd / memory that has already been freed). Instead, try:
scene *view = [[scene alloc] initWithFrame:CGRectMake(0, 0, IPHONE_WIDTH, IPHONE_HEIGHT) andManager:self];
viewController.view = view; // setView will release the old/retain the new
[view release]; // so you don't need to worry about releasing it later
Upvotes: 3
Reputation: 64428
This line:
[viewController.view release];
Is most likely your problem. Never send release to a property of an object except in the class' dealloc method. The view controllers view property accessors will handle retaining and releasing for you.
Upvotes: 0
Reputation: 15778
Got the solution:
- (void) changeScene: (Class) scene
{
BOOL animateTransition = true;
if(animateTransition){
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:window cache:YES]; //does nothing without this line.
}
if( viewController.view != nil ) {
[viewController.view retain]; //retain the view.
[viewController.view removeFromSuperview]; //remove view from window's subviews.
[viewController.view release]; //release gamestate
}
viewController.view = [[scene alloc] initWithFrame:CGRectMake(0, 0, IPHONE_WIDTH, IPHONE_HEIGHT) andManager:self];
//now set our view as visible
[window addSubview:viewController.view];
[window makeKeyAndVisible];
if(animateTransition){
[UIView commitAnimations];
}
}
It needs me to retain the view, but I don't know why this is necessary.
Upvotes: 0