crash sprite-kit dealloc skscene

crash - SKScene no puede desasignar la memoria, lo que genera un crecimiento limitado de la memoria



sprite-kit dealloc (3)

En un juego en el que estoy trabajando tengo un método para pasar a la siguiente escena. Se parece a esto:

func proceedToNextLevel() { // Go to next level self.physicsWorld.removeAllJoints() self.enumerateChildNodesWithName("cube", usingBlock: { (node: SKNode!, stop: UnsafeMutablePointer <ObjCBool>) -> Void in // do something with node or stop node.removeFromParent() }) player.removeFromParent() hud.removeFromParent() }

Cada nivel es una escena que hereda este método. (Tengo un GameScene.swift, y cada nivel es una subclase de él)

Este método en cada nivel se ve así:

override func proceedToNextLevel() { super.proceedToNextLevel() let transition = SKTransition.revealWithDirection(SKTransitionDirection.Right, duration: 3) let newScene: LevelFourScene = LevelFourScene.unarchiveFromFile("LevelFourScene") as! LevelFourScene newScene.scaleMode = SKSceneScaleMode.AspectFit self.view?.presentScene(newScene) }

Obviamente, esto es rápido y tu juego está en Objective C, pero ojalá entiendas la idea.

He estado luchando con esto por días, por alguna razón mis SKScenes no están deslocalizando correctamente, esto da como resultado un crecimiento limitado de la memoria ya que cada vez que salgo y entro en una escena, la memoria salta. Esto significa, después de decir 10 rondas del juego, que la aplicación falla. Por lo que sé, después de muchas comprobaciones, no tengo ningún ciclo de retención o referencias fuertes a las escenas y, aunque sé que las texturas están almacenadas en la memoria, una vez precargadas, la memoria no debería estar subiendo cada vez.

Así es como configuro skview y la primera escena en el controlador de visualización:

-(void)loadStartScreen{ SKView *theView = (SKView *) self.view; theView.showsFPS = YES; theView.showsNodeCount = YES; //Sprite Kit applies additional optimizations to improve rendering performance theView.ignoresSiblingOrder = YES; // Create and configure the scene. MainMenuScene *theScene = [MainMenuScene sceneWithSize:theView.bounds.size]; theScene.scaleMode = SKSceneScaleModeAspectFill; theScene.backgroundColor = [UIColor grayColor]; // Present the scene [theView presentScene:theScene];

Este es el código de mi MainMenuScene para crear y pasar a la siguiente escena:

SKScene *theScene; SKTransition *theTransition; switch (theTag.intValue) { case 0: // start game // stop music [[appDelegate musicPlayer]stop]; theScene = [[GameLevelScene alloc] initWithSize:self.view.bounds.size]; // transition type theTransition = [SKTransition fadeWithDuration:1.0]; break; case 1: // settings theScene = [[SettingsScene alloc] initWithSize:self.view.bounds.size]; // transition type theTransition = [SKTransition flipHorizontalWithDuration:1.0]; break; case 2: // iap theScene = [[IAPScene alloc] initWithSize:self.view.bounds.size]; // transition type theTransition = [SKTransition flipHorizontalWithDuration:1.0]; break; case 3: // unlocks screen NSLog(@"scene is %@",self.view.scene); theScene = [[deletmet alloc] initWithSize:self.view.bounds.size]; // transition type theTransition = [SKTransition flipHorizontalWithDuration:1.0]; NSLog(@"scene is after %@",self.view.scene); break; case 4: // level complete theScene = [[LevelCompleteScene alloc] initWithSize:self.view.bounds.size]; // transition type theTransition = [SKTransition flipHorizontalWithDuration:1.0]; break; case 5: // cheats theScene = [[CheatsScene alloc] initWithSize:self.view.bounds.size]; // transition type theTransition = [SKTransition flipHorizontalWithDuration:1.0]; break; default: break; }

Ahora sé que debes usar "[self.view presentScene:]", ya que SkView mantiene la escena, pero como nada funciona, he estado experimentando para ver por qué la escena no parece desasignar. Cuando intento presionar el botón para el caso 2 siguiente obtengo los NSlogs resultantes:

[self presentScene:theScene];

Resultado NSLOG = "IAP SCENE DEALLOC" pero el usuario no pasa a la siguiente escena.

[self presentScene:nil];

Resultado NSLOG = "IAP SCENE DEALLOC" pero el usuario no pasa a la siguiente escena.

[self.view presentScene:theScene];

No nslog resultados a pesar de que el MainMenuScene actual tiene un NSLOG para dealloc

[self.view presentScene:nil];

Resultado NSLOG = IAP SCENE DEALLOC y la pantalla se vuelve gris

Ahora todo esto es muy extraño, ya que seguramente cuando reciba un mensaje DEALLOC NSLOG, debería estar dándome el NSLOG para el desglose de la escena actual, también conocido como MainMenuScene, en lugar de la escena que debería estar cargando.

¿Estoy haciendo algo mal? Estoy trabajando incorrectamente con el SKView, cualquier ayuda sería muy apreciada ya que he leído una variedad de publicaciones que no han ayudado.

  • Actualización: este es el código de cada escena en la que me muevo hacia adelante y hacia atrás, advierto la falta de acciones o cualquier referencia fuerte a uno mismo:

Menú principal:

#import "MainMenuScene.h" #import "SKScene+SceneUtils.h" #import "GameLevelScene.h" #import "SettingsScene.h" #import "CreditsScene.h" #import "IAPScene.h" #import "UnlocksScene.h" #import "LevelCompleteScene.h" #import "CheatsScene.h" #import "AppDelegate.h" #import "UserDetails.h" #import "ItemBannerLabel.h" #import "ItemWindow.h" #import "TextureList.h" #import "TextureLoader.h" @interface MainMenuScene(){ SKSpriteNode *backgroundImage; SKSpriteNode *topBar; SKSpriteNode *bottomBar; SKSpriteNode *ladybirds; SKLabelNode *title; SKLabelNode *subtitle; SKLabelNode *coffee; ItemWindow *settingsWin; ItemWindow *iapWin; ItemWindow *unlocksWin; AGSpriteButton *startButton; AGSpriteButton *continueButton; AGSpriteButton *settingsButton; AGSpriteButton *iapButton; AGSpriteButton *unlocksButton; SKEmitterNode *theParticles; //SKAction *delay; //AppDelegate *appDelegate; } @end @implementation MainMenuScene #pragma mark - Scene Appears -(void)didMoveToView:(SKView *)view { // setup UI [self createUI]; // setup view [self setupView]; } -(void)willMoveFromView:(SKView *)view{ } #pragma mark - CreateUI -(void)createUI{ // scene size self.scene.size = [[TextureList sharedManager]returnTextureSize:@"kMMBg"]; // background self.scene.backgroundColor = [SKColor colorWithRed:0/255.0 green:0/255.0 blue:0/255.0 alpha:1.0]; // masked background backgroundImage = [SKSpriteNode spriteNodeWithTexture:[SKTexture textureWithImageNamed:kMMBg] size:[[TextureList sharedManager]returnTextureSize:@"kMMBg"]]; backgroundImage.position = screenCenter; backgroundImage.zPosition = self.zPosition+1; [self addChild:backgroundImage]; ladybirds = [SKSpriteNode spriteNodeWithTexture:[SKTexture textureWithImageNamed:kMMLadybirds] size:[[TextureList sharedManager]returnTextureSize:kMMLadybirds]]; ladybirds.position = CGPointMake(CGRectGetMaxX(self.frame)-ladybirds.frame.size.width/2, screenCenter.y); ladybirds.zPosition = bottomBar.zPosition+5; [self addChild:ladybirds]; // buttons startButton = [[AGSpriteButton alloc]initWithTexture:[SKTexture textureWithImageNamed:kMMStartBtn] color:[UIColor clearColor] size:[[TextureList sharedManager]returnTextureSize:kMMStartBtn]]; [startButton setLabelWithText:@"" andFont:[UIFont fontWithName:kFontName size:kFontSizeButton] withColor:nil]; startButton.position = CGPointMake(ladybirds.position.x-ladybirds.frame.size.width/4, ladybirds.position.y-ladybirds.frame.size.height/16); startButton.zPosition = ladybirds.zPosition+1; [startButton addTarget:self selector:@selector(buttonPressed:) withObject:[NSNumber numberWithInt:0] forControlEvent:AGButtonControlEventTouchUpInside]; [self addChild:startButton]; // emitter theParticles = [NSKeyedUnarchiver unarchiveObjectWithFile:[[NSBundle mainBundle] pathForResource:@"FlowerPetalParticle" ofType:@"sks"]]; theParticles.zPosition = backgroundImage.zPosition+1; theParticles.position = CGPointMake((CGRectGetMinX(self.scene.frame)),startButton.position.y); theParticles.particlePositionRange = CGVectorMake(0.0, CGRectGetMaxY(self.frame)-topBar.frame.size.height-bottomBar.frame.size.height); if ([[[UserDetails sharedManager]userDevice]isEqualToString:@"ipad"]) { theParticles.particleLifetime = 8.0; theParticles.particleScale = 0.5; theParticles.particleScaleRange = 0.2; } [self addChild:theParticles]; topBar = [SKSpriteNode spriteNodeWithColor:[UIColor whiteColor] size:[[TextureList sharedManager]returnTextureSize:kMMTopBar]]; topBar.position = CGPointMake(screenCenter.x, CGRectGetMaxY(self.frame)-topBar.frame.size.height/2); topBar.zPosition = theParticles.zPosition+1; [self addChild:topBar]; bottomBar = [SKSpriteNode spriteNodeWithColor:[UIColor whiteColor] size:[[TextureList sharedManager]returnTextureSize:kMMBottomBar]]; bottomBar.position = CGPointMake(screenCenter.x, CGRectGetMinY(self.frame)+bottomBar.frame.size.height/2); bottomBar.zPosition = theParticles.zPosition+1; [self addChild:bottomBar]; settingsWin = [[ItemWindow alloc]initWithImageNamed:kMMCreditsBtn withLabel:@"SETTINGS" setLabelTop:NO]; settingsWin.theLabel.fontColor = [UIColor blackColor]; settingsWin.theLabel.fontSize = 15; settingsWin.position = CGPointMake(CGRectGetMinX(self.frame)+settingsWin.frame.size.width/2+20, CGRectGetMinY(self.frame)+settingsWin.frame.size.height/2+25); settingsWin.zPosition = bottomBar.zPosition+1; [self addChild:settingsWin]; settingsButton = [[AGSpriteButton alloc]initWithTexture:nil color:nil size:CGSizeMake(settingsWin.size.width*2, settingsWin.size.height*2)]; [settingsButton setLabelWithText:@"" andFont:[UIFont fontWithName:kFontName size:kFontSizeButton] withColor:nil]; settingsButton.position = settingsWin.position; settingsButton.zPosition = settingsWin.zPosition+1; [settingsButton addTarget:self selector:@selector(buttonPressed:) withObject:[NSNumber numberWithInt:1] forControlEvent:AGButtonControlEventTouchUpInside]; [self addChild:settingsButton]; iapWin = [[ItemWindow alloc]initWithImageNamed:kMMIapBtn withLabel:@"SHOP" setLabelTop:NO]; iapWin.theLabel.fontColor = [UIColor blackColor]; iapWin.theLabel.fontSize = 15; iapWin.position = CGPointMake(settingsWin.position.x+iapWin.frame.size.width+30, settingsWin.position.y); iapWin.zPosition = bottomBar.zPosition+1; [self addChild:iapWin]; iapButton = [[AGSpriteButton alloc]initWithTexture:nil color:nil size:CGSizeMake(iapWin.size.width*2, iapWin.size.height*2)]; [iapButton setLabelWithText:@"" andFont:[UIFont fontWithName:kFontName size:kFontSizeButton] withColor:nil]; iapButton.position = iapWin.position; iapButton.zPosition = iapWin.zPosition+1; [iapButton addTarget:self selector:@selector(buttonPressed:) withObject:[NSNumber numberWithInt:2] forControlEvent:AGButtonControlEventTouchUpInside]; [self addChild:iapButton]; unlocksWin = [[ItemWindow alloc]initWithImageNamed:kMMUnlockBtn withLabel:@"UNLOCKS" setLabelTop:NO]; unlocksWin.theLabel.fontColor = [UIColor blackColor]; unlocksWin.theLabel.fontSize = 15; unlocksWin.position = CGPointMake(iapWin.position.x+unlocksWin.frame.size.width+30, iapWin.position.y); unlocksWin.zPosition = bottomBar.zPosition+1; [self addChild:unlocksWin]; unlocksButton = [[AGSpriteButton alloc]initWithTexture:nil color:nil size:CGSizeMake(unlocksWin.size.width*2, unlocksWin.size.height*2)]; [unlocksButton setLabelWithText:@"" andFont:[UIFont fontWithName:kFontName size:kFontSizeButton] withColor:nil]; unlocksButton.position = unlocksWin.position; unlocksButton.zPosition = unlocksWin.zPosition+1; [unlocksButton addTarget:self selector:@selector(buttonPressed:) withObject:[NSNumber numberWithInt:3] forControlEvent:AGButtonControlEventTouchUpInside]; [self addChild:unlocksButton]; // Labels title = [[SKLabelNode alloc]initWithFontNamed:kFontName]; if ([[[UserDetails sharedManager]userDevice]isEqualToString:@"iphone4"]) { title.fontSize = 60; } else{ title.fontSize = 75; } title.fontColor = [UIColor blackColor]; title.position = CGPointMake(topBar.frame.size.width/4, topBar.position.y-10); title.zPosition = topBar.zPosition+1; title.text = @"FLOWERS"; [self addChild:title]; subtitle = [[SKLabelNode alloc]initWithFontNamed:kFontName]; if ([[[UserDetails sharedManager]userDevice]isEqualToString:@"iphone4"]) { subtitle.fontSize = 24; } else{ subtitle.fontSize = 30; } subtitle.fontColor = [UIColor grayColor]; subtitle.position = CGPointMake(title.position.x, title.position.y-title.frame.size.height/2-10); subtitle.zPosition = topBar.zPosition+1; subtitle.text = @"THE BEAUTIFUL MEADOW"; [self addChild:subtitle]; AGSpriteButton *testButton3 = [[AGSpriteButton alloc]initWithTexture:[SKTexture textureWithImageNamed:kMMIapBtn] color:[UIColor clearColor] size:[[TextureList sharedManager]returnTextureSize:kMMIapBtn]]; [testButton3 setLabelWithText:@"" andFont:[UIFont fontWithName:kFontName size:kFontSizeButton] withColor:nil]; testButton3.position = CGPointMake(bottomRight.x-testButton3.frame.size.width/1.5, bottomRight.y+settingsButton.frame.size.height/1.5); testButton3.zPosition = interfaceLayer; [testButton3 addTarget:self selector:@selector(buttonPressed:) withObject:[NSNumber numberWithInt:4] forControlEvent:AGButtonControlEventTouchUpInside]; [self addChild:testButton3]; AGSpriteButton *testButton4 = [[AGSpriteButton alloc]initWithTexture:[SKTexture textureWithImageNamed:kMMIapBtn] color:[UIColor clearColor] size:[[TextureList sharedManager]returnTextureSize:kMMIapBtn]]; [testButton4 setLabelWithText:@"" andFont:[UIFont fontWithName:kFontName size:kFontSizeButton] withColor:nil]; testButton4.position = CGPointMake(testButton3.position.x-testButton4.frame.size.width, bottomCenter.y+settingsButton.size.height/1.5); testButton4.zPosition = interfaceLayer; [testButton4 addTarget:self selector:@selector(buttonPressed:) withObject:[NSNumber numberWithInt:5] forControlEvent:AGButtonControlEventTouchUpInside]; [self addChild:testButton4]; if ([[[UserDetails sharedManager]userDevice] isEqualToString:@"ipad"]) { title.fontSize = 105; title.position = CGPointMake(topBar.frame.size.width/6+20, topBar.position.y+10); subtitle.position = CGPointMake(title.position.x, title.position.y-title.frame.size.height/2-10); subtitle.fontSize = 41; settingsWin.theLabel.fontSize = 25; iapWin.theLabel.fontSize = 25; unlocksWin.theLabel.fontSize = 25; settingsWin.position = CGPointMake(CGRectGetMinX(self.frame)+settingsWin.frame.size.width/2+20, CGRectGetMinY(self.frame)+settingsWin.frame.size.height+25); iapWin.position = CGPointMake(settingsWin.position.x+iapWin.frame.size.width+30, settingsWin.position.y); unlocksWin.position = CGPointMake(iapWin.position.x+unlocksWin.frame.size.width+30, settingsWin.position.y); } } #pragma mark - Setup View -(void)setupView{ // setup music players slightly quieter music now /*appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate]; [self fadeVolumeIn:[appDelegate musicPlayer] toVolume:0.45]; [[appDelegate soundFxPlayer]setVolume:0.25]; [[appDelegate soundFxPlayer]play]; // no continue if the user has not progressed past level 1 if ([[UserDetails sharedManager]userCurrentLevel] <= 1) { continueButton.userInteractionEnabled = NO; continueButton.hidden = YES; } else{ continueButton.userInteractionEnabled = YES; continueButton.hidden = NO; }*/ } #pragma mark - Interaction -(void)buttonPressed:(NSNumber*)theTag{ SKScene *theScene; SKTransition *theTransition; switch (theTag.intValue) { case 0: // start game // stop music //[[appDelegate musicPlayer]stop]; theScene = [[GameLevelScene alloc] initWithSize:self.view.bounds.size]; // transition type theTransition = [SKTransition fadeWithDuration:1.0]; break; case 1: // settings theScene = [[SettingsScene alloc] initWithSize:self.view.bounds.size]; // transition type theTransition = [SKTransition flipHorizontalWithDuration:1.0]; break; case 2: // iap theScene = [[IAPScene alloc] initWithSize:self.view.bounds.size]; // transition type theTransition = [SKTransition flipHorizontalWithDuration:1.0]; break; case 3: // unlocks screen theScene = [[UnlocksScene alloc] initWithSize:self.view.bounds.size]; // transition type theTransition = [SKTransition flipHorizontalWithDuration:1.0]; break; case 4: // level complete theScene = [[LevelCompleteScene alloc] initWithSize:self.view.bounds.size]; // transition type theTransition = [SKTransition flipHorizontalWithDuration:1.0]; break; case 5: // cheats theScene = [[CheatsScene alloc] initWithSize:self.view.bounds.size]; // transition type theTransition = [SKTransition flipHorizontalWithDuration:1.0]; break; default: break; } // play sound [self menuButtonPressed]; [self.view presentScene:theScene transition:theTransition]; } @end

Pantalla de configuración:

#import "SettingsScene.h" #import "SKScene+SceneUtils.h" #import "AGSpriteButton.h" #import "ItemBannerLabel.h" #import "TextureList.h" #import "UnlockController.h" #import "UserDetails.h" #import "TutorialFlowerTarget.h" #import "CreditsScene.h" @interface SettingsScene(){ AGSpriteButton *backButton; AGSpriteButton *resetButton; AGSpriteButton *resetTutorialsButton; AGSpriteButton *creditsButton; ItemBannerLabel *titleLabel; SKLabelNode *copyrightLabel; UIAlertView *resetGameAlert; UIAlertView *resetTutAlert; SKScene *theScene; SKTransition *theTransition; SKSpriteNode *menuBg; } @end @implementation SettingsScene #pragma mark - SCENE APPEARS -(void)didMoveToView:(SKView *)view { // setup UI [self createUI]; } #pragma mark - CREATE UI -(void)createUI{ // background self.scene.backgroundColor = [UIColor whiteColor]; menuBg = [[SKSpriteNode alloc]initWithTexture:[SKTexture textureWithImageNamed:kMDBg] color:nil size:[[TextureList sharedManager]returnTextureSize:@"kMDBg"]]; menuBg.position = screenCenter; menuBg.zPosition = self.zPosition+1; [self addChild:menuBg]; // labels titleLabel = [[ItemBannerLabel alloc]initWithBgImageNamed:kMDTitle withLabel:@"GAME SETTINGS" withfont:kFontName withSize:kFontSizeMDTitle]; titleLabel.position = CGPointMake(topLeft.x+titleLabel.frame.size.width/2+10,topLeft.y-titleLabel.frame.size.height/2-10); titleLabel.zPosition = interfaceLayer; [self addChild:titleLabel]; copyrightLabel = [SKLabelNode labelNodeWithFontNamed:kFontName]; copyrightLabel.text = [NSString stringWithFormat:@"COPYRIGHT © 2015 RICHARD ACHERKI"]; copyrightLabel.fontSize = kFontSizeMDSmall; copyrightLabel.fontColor = [UIColor blackColor]; copyrightLabel.verticalAlignmentMode = SKLabelVerticalAlignmentModeCenter; copyrightLabel.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeCenter; copyrightLabel.position = CGPointMake(bottomCenter.x, bottomCenter.y+copyrightLabel.frame.size.height); copyrightLabel.zPosition = interfaceLayer; [self addChild:copyrightLabel]; // buttons if ([[[UserDetails sharedManager]userDevice]isEqualToString:@"ipad"]) { resetTutorialsButton = [[AGSpriteButton alloc]initWithTexture:[SKTexture textureWithImageNamed:kMDButton] color:nil size:CGSizeMake([[TextureList sharedManager]returnTextureSize:kMDButton].width*4, [[TextureList sharedManager]returnTextureSize:kMDButton].height*2)]; [resetTutorialsButton setLabelWithText:@"RESET TUTORIALS" andFont:[UIFont fontWithName:kFontName size:kFontSizeButton] withColor:[UIColor whiteColor]]; resetTutorialsButton.position = CGPointMake(screenCenter.x, titleLabel.position.y-titleLabel.frame.size.height/2-resetTutorialsButton.frame.size.height/2-30); resetTutorialsButton.zPosition = menuBg.zPosition+1; [resetTutorialsButton addTarget:self selector:@selector(buttonPressed:) withObject:[NSNumber numberWithInt:0] forControlEvent:AGButtonControlEventTouchUpInside]; } else{ resetTutorialsButton = [[AGSpriteButton alloc]initWithTexture:[SKTexture textureWithImageNamed:kMDButton] color:nil size:CGSizeMake([[TextureList sharedManager]returnTextureSize:kMDButton].width*2, [[TextureList sharedManager]returnTextureSize:kMDButton].height)]; [resetTutorialsButton setLabelWithText:@"RESET TUTORIALS" andFont:[UIFont fontWithName:kFontName size:kFontSizeButton] withColor:[UIColor whiteColor]]; resetTutorialsButton.position = CGPointMake(screenCenter.x, titleLabel.position.y-titleLabel.frame.size.height/2-resetTutorialsButton.frame.size.height/2-30); resetTutorialsButton.zPosition = menuBg.zPosition+1; [resetTutorialsButton addTarget:self selector:@selector(buttonPressed:) withObject:[NSNumber numberWithInt:0] forControlEvent:AGButtonControlEventTouchUpInside]; } [self addChild:resetTutorialsButton]; if ([[[UserDetails sharedManager]userDevice]isEqualToString:@"ipad"]) { resetButton = [[AGSpriteButton alloc]initWithTexture:[SKTexture textureWithImageNamed:kMDButton] color:nil size:CGSizeMake([[TextureList sharedManager]returnTextureSize:kMDButton].width*4, [[TextureList sharedManager]returnTextureSize:kMDButton].height*2)]; [resetButton setLabelWithText:@"RESET GAME" andFont:[UIFont fontWithName:kFontName size:kFontSizeButton] withColor:[UIColor whiteColor]]; resetButton.position = CGPointMake(resetTutorialsButton.position.x,resetTutorialsButton.position.y-resetTutorialsButton.frame.size.height-20); resetButton.zPosition = menuBg.zPosition+1; [resetButton addTarget:self selector:@selector(buttonPressed:) withObject:[NSNumber numberWithInt:1] forControlEvent:AGButtonControlEventTouchUpInside]; } else{ resetButton = [[AGSpriteButton alloc]initWithTexture:[SKTexture textureWithImageNamed:kMDButton] color:nil size:CGSizeMake([[TextureList sharedManager]returnTextureSize:kMDButton].width*2, [[TextureList sharedManager]returnTextureSize:kMDButton].height)]; [resetButton setLabelWithText:@"RESET GAME" andFont:[UIFont fontWithName:kFontName size:kFontSizeButton] withColor:[UIColor whiteColor]]; resetButton.position = CGPointMake(resetTutorialsButton.position.x,resetTutorialsButton.position.y-resetTutorialsButton.frame.size.height-20); resetButton.zPosition = menuBg.zPosition+1; [resetButton addTarget:self selector:@selector(buttonPressed:) withObject:[NSNumber numberWithInt:1] forControlEvent:AGButtonControlEventTouchUpInside]; } [self addChild:resetButton]; if ([[[UserDetails sharedManager]userDevice]isEqualToString:@"ipad"]) { creditsButton = [[AGSpriteButton alloc]initWithTexture:[SKTexture textureWithImageNamed:kMDButton] color:nil size:CGSizeMake([[TextureList sharedManager]returnTextureSize:kMDButton].width*4, [[TextureList sharedManager]returnTextureSize:kMDButton].height*2)]; [creditsButton setLabelWithText:@"CREDITS" andFont:[UIFont fontWithName:kFontName size:kFontSizeButton] withColor:[UIColor whiteColor]]; creditsButton.position = CGPointMake(resetButton.position.x,resetButton.position.y-resetButton.frame.size.height-20); creditsButton.zPosition = menuBg.zPosition+1; [creditsButton addTarget:self selector:@selector(buttonPressed:) withObject:[NSNumber numberWithInt:2] forControlEvent:AGButtonControlEventTouchUpInside]; } else{ creditsButton = [[AGSpriteButton alloc]initWithTexture:[SKTexture textureWithImageNamed:kMDButton] color:nil size:CGSizeMake([[TextureList sharedManager]returnTextureSize:kMDButton].width*2, [[TextureList sharedManager]returnTextureSize:kMDButton].height)]; [creditsButton setLabelWithText:@"CREDITS" andFont:[UIFont fontWithName:kFontName size:kFontSizeButton] withColor:[UIColor whiteColor]]; creditsButton.position = CGPointMake(resetButton.position.x,resetButton.position.y-resetButton.frame.size.height-20); creditsButton.zPosition = menuBg.zPosition+1; [creditsButton addTarget:self selector:@selector(buttonPressed:) withObject:[NSNumber numberWithInt:2] forControlEvent:AGButtonControlEventTouchUpInside]; } [self addChild:creditsButton]; backButton = [[AGSpriteButton alloc]initWithTexture:[SKTexture textureWithImageNamed:kMDButton] color:nil size:[[TextureList sharedManager]returnTextureSize:kMDButton]]; [backButton setLabelWithText:@"BACK" andFont:[UIFont fontWithName:kFontName size:kFontSizeButton] withColor:[UIColor whiteColor]]; backButton.position = CGPointMake(bottomRight.x-backButton.frame.size.width/2-10, bottomRight.y+backButton.frame.size.height/2+10); backButton.zPosition = menuBg.zPosition+1; [backButton addTarget:self selector:@selector(buttonPressed:) withObject:[NSNumber numberWithInt:3] forControlEvent:AGButtonControlEventTouchUpInside]; [self addChild:backButton]; } #pragma mark - BUTTON PRESSED -(void)buttonPressed:(NSNumber*)theTag{ if (theTag.intValue == 0) { // reset tutorials resetTutAlert = [[UIAlertView alloc]initWithTitle:@"RESET TUTORIALS" message:@"Are you sure you want to reset tutorials?/nThis will cause all tutorials to show again when playing the game." delegate:self cancelButtonTitle:@"No" otherButtonTitles:@"Yes", nil]; [resetTutAlert show]; } else if (theTag.intValue == 1) { // reset game resetGameAlert = [[UIAlertView alloc]initWithTitle:@"RESET THE GAME" message:@"Are you sure you want to wipe your game progression?/nThis will remove all unlocks, scores and level progression." delegate:self cancelButtonTitle:@"No" otherButtonTitles:@"Yes", nil]; [resetGameAlert show]; } else if (theTag.intValue == 2) { // credits menu // play sound [self menuButtonPressed]; theScene = [[CreditsScene alloc] initWithSize:self.view.bounds.size]; theTransition = [SKTransition flipHorizontalWithDuration:1.0]; [self.view presentScene:theScene transition:theTransition]; } else if (theTag.intValue == 3) { // main menu // play sound [self menuButtonPressed]; // scene to move to theScene = [[MainMenuScene alloc] initWithSize:self.view.bounds.size]; // transition type theTransition = [SKTransition flipHorizontalWithDuration:1.0]; [self.view presentScene:theScene transition:theTransition]; } } #pragma mark - RESET TUTORIALS -(void)resetTutorials{ for (id theObject in [[UserDetails sharedManager]userTutorials]) { TutorialFlowerTarget *theTut= [[[UserDetails sharedManager]userTutorials]objectForKey:theObject]; [theTut setTriggered:NO]; } [[UserDetails sharedManager]saveData]; } #pragma mark - RESET UNLOCKS -(void)resetUnlocks{ [[UnlockController sharedManager]resetGame]; }


En función de su código publicado, le sugiero que agregue esto a su MainMenu:

-(void) willMoveFromView:(SKView *)view { [self removeAllChildren]; backgroundImage = nil; topBar = nil; bottomBar = nil; ladybirds = nil; title = nil; subtitle = nil; coffee = nil; settingsWin = nil; iapWin = nil; unlocksWin = nil; startButton = nil; continueButton = nil; settingsButton = nil; iapButton = nil; unlocksButton = nil; theParticles = nil; }

Agregue esto a su escena de configuración:

-(void) willMoveFromView:(SKView *)view { [self removeAllChildren]; backButton = nil; resetButton = nil; resetTutorialsButton = nil; creditsButton = nil; titleLabel = nil; copyrightLabel = nil; resetGameAlert = nil; resetTutAlert = nil; theScene = nil; theTransition = nil; menuBg = nil; }

Tenga en cuenta que SK usa su propio almacenamiento en caché, sobre el cual no tiene control. Esto significa que verá un aumento en la memoria las primeras veces que cambie de escena, pero se estabilizará en algún punto. Te sugiero que te muevas hacia adelante y hacia atrás de 15 a 20 veces y veas qué pasa.


Podría estar equivocado, pero sospecho que tu clase de botón es tu ofensor. Cuando usted llama...

[testButton4 addTarget:self selector:@selector(buttonPressed:) withObject:[NSNumber numberWithInt:5] forControlEvent:AGButtonControlEventTouchUpInside];

Pasas self siendo esa escena. En la clase de botón el método ...

-(void)addTarget:(id)target selector:(SEL)selector withObject:(id)object forControlEvent:(AGButtonControlEvent)controlEvent { //check whether selector is already saved, otherwise it will get called twice if (marrSelectors == nil) { marrSelectors = [NSMutableArray new]; } NSMutableDictionary *mdicSelector = [[NSMutableDictionary alloc]init]; [mdicSelector setObject:target forKey:@"target"]; [mdicSelector setObject:[NSValue valueWithPointer:selector] forKey:@"selector"]; if (object) { [mdicSelector setObject:object forKey:@"object"]; } [mdicSelector setObject:[NSNumber numberWithInt:controlEvent] forKey:@"controlEvent"]; [marrSelectors addObject:mdicSelector]; }

Tenga en cuenta esto ..

[mdicSelector setObject:target forKey:@"target"];

el objetivo es tu escena y está siendo arrojado a un diccionario en el que se lanza a una matriz. Entonces, en teoría, ese botón ahora tiene una fuerte referencia a tu escena y tu escena tiene una referencia a ese botón.

Para probar esta teoría, configure todos sus botones como nulos antes de llamar

[self.view presentScene:theScene transition:theTransition];

Y si estoy en lo correcto, eso debería romper la fuerte referencia entre ellos. Espero que eso ayude y sea el problema.