2015-05-13 7 views
5

Ich habe seit Tagen damit zu kämpfen, aus irgendeinem Grund werden meine SKScenes nicht korrekt freigegeben, dies führt zu begrenztem Speicherwachstum, da jedesmal wenn ich gehe und eine Szene eintritt, der Speicher springt oben. Das heißt nach etwa 10 Runden des Spiels stürzt die App ab. Soweit ich weiß, habe ich nach vielen Überprüfungen keine Retain-Zyklen oder starke Verweise auf die Szenen selbst und obwohl ich weiß, dass Texturen zwischengespeichert und im Speicher gehalten werden, sollte der Speicher nach dem Laden nicht jedes Mal hochgehen.SKScene kann Speicher nicht freigeben, was zu begrenztem Speicherwachstum führt

Dies ist, wie ich Setup die skview und erste Szene in der Viewcontroller:

-(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]; 

Dies ist der Code aus meiner MainMenuScene ist in die nächste Szene zu erstellen und bewegen:

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; 
    } 

Jetzt Ich weiß, dass Sie "[self.view presentScene:]" verwenden sollten, da der SkView die Szene enthält, aber weil nichts funktioniert, habe ich experimentiert, um zu sehen, warum die Szene nicht freizulegen scheint. Wenn ich versuche, die Taste für Fall 2 Drücken folgenden erhalte ich die resultierenden NSlogs:

[self presentScene:theScene]; 

NSLog result = „IAP SZENE DEALLOC“ der Benutzer ist jedoch nicht auf die nächste Szene gemacht.

[self presentScene:nil]; 

NSLog result = "IAP SZENE DEALLOC" der Benutzer ist jedoch nicht auf die nächste Szene gemacht.

[self.view presentScene:theScene]; 

Keine NSLog Ergebnisse, obwohl die aktuelle MainMenuScene ein NSLog für dealloc hat

[self.view presentScene:nil]; 

NSLog result = IAP SZENE DEALLOC und der Bildschirm wird grau

Jetzt ist das alles sehr seltsam, wie sicher Wenn ich eine DEALLOC NSLOG-Nachricht erhalte, sollte sie mir den NSLOG für den Dealloc der aktuellen Szene aka MainMenuScene geben und nicht die Szene, die geladen werden soll.

Mache ich etwas falsch? Arbeite ich falsch mit dem SKView, würde jede Hilfe sehr geschätzt, da ich eine Vielzahl von Beiträgen gelesen habe, die alle nicht geholfen haben.

  • Update: Dies ist der Code für jede Szene, die ich zwischen hin und her bewegte, bemerken das Fehlen von Aktionen oder irgendwelchen starken Referenzen an mich selbst:

Hauptmenü:

#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 

Einstellungen Screen:

#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]; 
} 
+0

Gibt es Animationen, wenn Sie die nächste Szene präsentieren? Ich habe gesehen, dass Knoten mit laufenden Animationen Szenen nicht freigeben. Oder wenn deine Szene eine SKAction ausführt, die das auch verursachen könnte. Ich denke, dass Sie mehr Code zeigen müssen, damit wir sehen können, was den Zurückhaltezyklus verursachen würde. –

+0

Hallo Ben, ich habe den Code für jede Szene in ihrer Gesamtheit hinzugefügt, hoffentlich sollte das helfen. – SmokersCough

+0

Ich bin nicht etwas zu sehen, dass dies dazu führen würde, aber können Sie den Code für 'menuButtonPressed' –

Antwort

4

Ich könnte falsch liegen, aber ich vermute, dass Ihre Knopfklasse Ihr Täter ist. Wenn Sie anrufen ...

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

Sie passieren self wird diese Szene. dies der Button-Klasse die Methode ..

-(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]; 
} 

Hinweis ..

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

Ziel ist Ihre Szene und in ein Wörterbuch wird in das geworfen wird in ein Array geworfen. In der Theorie hat diese Schaltfläche nun einen starken Bezug zu Ihrer Szene und Ihre Szene hat einen Verweis auf diese Schaltfläche.

diese Theorie alle Ihre Tasten auf Null gesetzt, um zu testen, bevor

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

Aufruf Und wenn ich richtig bin, dass die starke Bezug zueinander brechen sollte. Hoffentlich hilft das und ist das Problem.

+2

Hallo Leute, Vielen Dank an alle, dass Sie sich die Zeit genommen haben, sich mit mir zu befassen. SUPER BIG Danke an Skyler Lauren, dass sie mich in die richtige Richtung gelenkt hat! Er war in der Tat richtig, es stellt sich heraus, der Schuldige ist die AGSpriteButton-Klasse! Es scheint, dass es ein Wörterbuch der Selektor-Aktionen hält und dies verursachte Retain-Zyklen, aber die AGSpriteButtons auf Null gesetzt schien nicht zu arbeiten, versuchen Sie stattdessen mit: [yourAgsButton removeAllTargets]; Nach der Verwendung dieser meine Dealloc-Methoden werden aufgerufen, wenn Szenen verlassen wurden und BOOM mein Speicher begann – SmokersCough

+1

Friday Ich konnte helfen. Bin selbst auf ein ähnliches Problem gestoßen, indem ich einen benutzerdefinierten Delegaten nicht auf schwach gestellt habe. Tage und Tage, die damit verbracht wurden, es herauszufinden. :) Viel Glück mit Ihrer App. –

+0

Ich wünschte, ich könnte diese Antwort mehr als einmal abstimmen. –

0

Basierend auf Ihren Code geschrieben, ich schlage vor, Sie th hinzufügen Ihre MainMenu ist:

-(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; 
} 

diese SettingsScene zu Ihrer hinzufügen:

-(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; 
} 

Denken Sie daran, dass SK seinen eigenen Cache verwendet, die Sie haben keine Kontrolle über.Das bedeutet, dass Sie die ersten Male, wenn Sie die Szenen wechseln, einen erhöhten Speicher sehen werden, aber es wird sich irgendwann ausgleichen. Ich schlage vor, Sie bewegen sich 15 bis 20 Mal hin und her und sehen, was passiert.

+0

Ja, aber ich bin mir nicht sicher, ob das hilft, da das Problem scheinbar darin besteht, dass die Szene nicht veröffentlicht wird. Dadurch würden alle diese Elemente automatisch entfernt, solange sie nicht an anderer Stelle referenziert werden. Aber danke für den Vorschlag. – SmokersCough

+0

@SmokersCough - "Die starke Referenz auf die alte Szene wird entfernt. Wenn Sie die Szene nach dem Übergang beibehalten müssen, muss Ihre App ihren eigenen starken Bezug zur alten Szene behalten." Dies ist nach den Unterlagen. Wenn Sie also nicht absichtlich einen starken Bezug zu Ihrer alten Szene haben, wird sie und alle anderen Elemente freigegeben. – sangony

+0

Tut mir leid, ich bin ein wenig verwirrt, ich habe keinen starken Bezug auf die Szene, will ich auch nicht, die Szene ist auch nicht für irgendwelche Benachrichtigungen registriert. Aber die Szene wird im Gedächtnis behalten, da ich kein dealloc nslog sehe.Sicherlich sollte ich nicht jedes Objekt manuell löschen müssen, damit dies funktioniert? – SmokersCough

0

In einem Spiel, an dem ich arbeite, habe ich eine Methode, um zur nächsten Szene überzugehen. Es sieht so aus:

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() 
} 

Jede Ebene ist eine Szene, die diese Methode erbt. (Ich habe einen GameScene.swift, und jede Ebene ist eine Unterklasse davon)

Diese Methode in jeder Ebene sieht wie folgt aus:

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) 
} 

Offensichtlich ist dies schnell und Ihr Spiel ist in Objective C, aber hoffentlich Du hast die Idee.

+0

Danke, aber wenn du dir das anschaust, ersetzst du die geladene Szene, indem ich das presentScene benutze, aber meine vorherige Szene scheint nicht veröffentlicht zu werden, was bedeutet, dass ich jedes Mal eine ganz neue Szene hinzufüge . – SmokersCough

Verwandte Themen