SKScene Fails to deallocate memory resulting in bounded memory growth

后端 未结 3 1088
暖寄归人
暖寄归人 2021-01-06 01:05

I have been struggling with this for days, for some reason my SKScenes are not deallocating correctly, this results in bounded memory growth as each time i exit and enter a

相关标签:
3条回答
  • 2021-01-06 01:06

    I could be wrong but I suspect your button class is your offender. When you call...

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

    You pass self being that scene. In the button class the method..

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

    Note this..

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

    target is your scene and it is being tossed into a dictionary in that is tossed into an array. So in theory that button now has a strong reference to your scene and your scene has a reference to that button.

    To test this theory set all of your buttons to nil before calling

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

    And if I am correct that should break the strong reference to each other. Hopefully that helps and is the issue.

    0 讨论(0)
  • 2021-01-06 01:09

    Based on your posted code, I suggest you add this to your 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;
    }
    

    Add this to your SettingsScene:

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

    Keep in mind that SK uses its own caching which you have no control over. This means you will see an increase in memory the first couple of times you switch scenes but it will level out at some point. I suggest you move back and forth 15 to 20 times and see what happens.

    0 讨论(0)
  • 2021-01-06 01:25

    In a game I'm working on I have a method for going on to the next scene. It looks like this:

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

    Each level is a scene that inherits this method. (I have a GameScene.swift, and every level is a subclass of it)

    This method in each level looks like this:

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

    Obviously this is swift and your game is in Objective C but hopefully you get the idea.

    0 讨论(0)
提交回复
热议问题