15

子として 3 つの skscenes を持つビュー コントローラーがあります。

あるシーンから別のシーンに移行すると、古い skscene の割り当てが解除されません。

あたかもそこになかったかのように割り当てを解除したいのです。

例:

最初にアプリをロードしたとき、1 つの skscene だけが表示され (100 MB のメモリを消費するとします)、別の skscene (100 mb 以上) に移行し、3 つ目 (300 mb のメモリ) に移行します。

最終的に 300MB のメモリが必要になるため、常に 100MB を保持したいと考えています。

どうすればこれを達成できますか?

My view controller: 

//
//  ViewController.m
//  Paddle Jumper
//
//  Created by Chance Daniel on 1/18/14.
//  Copyright (c) 2014 Max Hudson. All rights reserved.
//

#import "Flurry.h"
#import "ViewController.h"
#import "startViewController.h"

@implementation ViewController{
    BOOL sceneSetUp;
}

- (void)viewWillLayoutSubviews
{
    if(!sceneSetUp){

        [super viewWillLayoutSubviews];

        // Configure the view.
        SKView * skView = (SKView *)self.view;
        //skView.showsFPS = YES;
        //skView.showsNodeCount = YES;

        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
        if([[defaults objectForKey:@"firstTime"] intValue] != 1){
            [defaults setObject:[NSNumber numberWithInt:1] forKey:@"firstTime"];

            [defaults setObject:@"ggr" forKey:@"skinSelected"];
            [defaults setObject:[NSNumber numberWithInt:2] forKey:@"ggrOwned"];

            [defaults setObject:[NSNumber numberWithInt:5000] forKey:@"gona"];
            [defaults setObject:[NSNumber numberWithInt:1500] forKey:@"points"];
            [defaults setObject:[NSNumber numberWithInt:7] forKey:@"livesLeftValue"];
            [defaults setObject:[NSNumber numberWithInt:3] forKey:@"shieldsLeftValue"];
            [defaults setObject:[NSNumber numberWithInt:2] forKey:@"lvlTwoLeftValue"];
            [defaults setObject:[NSNumber numberWithInt:0] forKey:@"lvlThreeLeftValue"];
        }

        if(![defaults objectForKey:@"tut_game1"]){
            [defaults setObject:[NSNumber numberWithInt:1] forKey:@"tut_game1"];
            [defaults setObject:[NSNumber numberWithInt:1] forKey:@"tut_store"];
            [defaults setObject:[NSNumber numberWithInt:1] forKey:@"tut_daily"];
        }

        [defaults synchronize];

        // Create and configure the scene.
        SKScene * startScene = [StartViewController sceneWithSize:skView.bounds.size];
        startScene.scaleMode = SKSceneScaleModeAspectFill;

        // Present the scene.
        [skView presentScene:startScene];
        //[skView presentScene:scene];

        sceneSetUp = YES;
    }

}

-(void) switchScene{

}

- (BOOL)shouldAutorotate
{
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations
{
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
        return UIInterfaceOrientationMaskAllButUpsideDown;
    } else {
        return UIInterfaceOrientationMaskAll;
    }
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Release any cached data, images, etc that aren't in use.
}

@end

An SKScene that won't release: //
//  SettingsSKScene.m
//  Paddle Jumper
//
//  Created by Max Hudson on 3/15/14.
//  Copyright (c) 2014 Max Hudson. All rights reserved.
//

#import "SettingsSKScene.h"
#import "gameViewController.h"
#import "StoreScene.h"

@interface SettingsSKScene (){
    SKSpriteNode *bg;
    SKSpriteNode *masterOverlay;
    SKSpriteNode *wbox;
    SKSpriteNode *gamecenter;
    SKSpriteNode *max;
    SKSpriteNode *chance;
    SKSpriteNode *bryce;
    SKSpriteNode *home;
    SKSpriteNode *play;

    SKSpriteNode *chance_link;
    SKSpriteNode *max_link;
    SKSpriteNode *bryce_link;

    SKSpriteNode *fbButton;
    SKSpriteNode *fbToggleYes;
    SKSpriteNode *fbToggleNo;

    SKLabelNode *story1;
    SKLabelNode *story2;
    SKLabelNode *story3;

    SKLabelNode *chance_name;
    SKLabelNode *max_name;
    SKLabelNode *bryce_name;

    SKLabelNode *chance_role;
    SKLabelNode *max_role;
    SKLabelNode *bryce_role;

    SKLabelNode *chance_handle;
    SKLabelNode *max_handle;
    SKLabelNode *bryce_handle;

    SKTexture *bg_texture;
    SKTexture *gamecenter_texture;
    SKTexture *wbox_texture;
    SKTexture *max_texture;
    SKTexture *chance_texture;
    SKTexture *bryce_texture;
    SKTexture *home_texture;
    SKTexture *play_texture;
    SKTexture *fb_texture;
    SKTexture *toggle_yes_texture;
    SKTexture *toggle_no_texture;
}

@end

@implementation SettingsSKScene

-(id) initWithSize:(CGSize)size{
    if(self = [super initWithSize:size]){
        masterOverlay = [SKSpriteNode spriteNodeWithColor:[SKColor blackColor] size:self.frame.size];
        masterOverlay.position = CGPointMake(self.frame.size.width/2, self.frame.size.height/2);
        [self addChild:masterOverlay];

        bg_texture = [SKTexture textureWithImageNamed:@"settings_bg"];
        wbox_texture = [SKTexture textureWithImageNamed:@"white_rect_bg"];
        gamecenter_texture = [SKTexture textureWithImageNamed:@"gc"];
        max_texture = [SKTexture textureWithImageNamed:@"max"];
        chance_texture = [SKTexture textureWithImageNamed:@"chance"];
        bryce_texture = [SKTexture textureWithImageNamed:@"bryce"];
        home_texture = [SKTexture textureWithImageNamed:@"home_light"];
        play_texture = [SKTexture textureWithImageNamed:@"play_light"];
        fb_texture = [SKTexture textureWithImageNamed:@"fb_light"];
        toggle_yes_texture = [SKTexture textureWithImageNamed:@"toggle_yes"];
        toggle_no_texture = [SKTexture textureWithImageNamed:@"toggle_no"];

        NSArray *to_preload = @[bg_texture, wbox_texture, gamecenter_texture, max_texture, chance_texture, bryce_texture, home_texture, play_texture, fb_texture, toggle_yes_texture, toggle_no_texture];

        [SKTexture preloadTextures:to_preload withCompletionHandler:^{
            [self fadeRemove:masterOverlay];
            [self initialize];
        }];
    }
    return self;
}

-(void) fadeRemove: (SKNode *) node{
    double duration = arc4random() % 10;
    duration *= 0.05;
    SKAction *fadeOut = [SKAction fadeOutWithDuration:0.1+duration];
    SKAction *remove = [SKAction runBlock:^{
        [node removeFromParent];
    }];

    [node runAction:[SKAction sequence:@[fadeOut, remove]]];
}

-(void) initialize{
    bg = [SKSpriteNode spriteNodeWithTexture:bg_texture];
    bg.position = CGPointMake(self.frame.size.width/2, self.frame.size.height/2);
    bg.zPosition = 0;

    wbox = [SKSpriteNode spriteNodeWithTexture:wbox_texture];
    wbox.position = CGPointMake(self.frame.size.width/2, 70);
    wbox.alpha = 0.8;
    wbox.zPosition = 2;

    gamecenter = [SKSpriteNode spriteNodeWithTexture:gamecenter_texture];
    gamecenter.position = CGPointMake(self.frame.size.width/2 + 100, self.frame.size.height/2-2);
    gamecenter.name = @"gc";
    gamecenter.zPosition = 2;

    fbButton = [SKSpriteNode spriteNodeWithTexture:fb_texture];
    fbButton.size = CGSizeMake(36, 36);
    fbButton.position = CGPointMake(self.frame.size.width/2 - 115, self.frame.size.height/2-2);
    fbButton.name = @"fb";
    fbButton.zPosition = 2;

    fbToggleNo = [SKSpriteNode spriteNodeWithTexture:toggle_no_texture];
    fbToggleNo.position = CGPointMake(self.frame.size.width/2 - 50, self.frame.size.height/2-2);
    fbToggleNo.size = CGSizeMake(fbToggleNo.size.width/3, fbToggleNo.size.height/3);
    fbToggleNo.name = @"fbno";
    fbToggleNo.zPosition = 2;

    fbToggleYes = [SKSpriteNode spriteNodeWithTexture:toggle_yes_texture];
    fbToggleYes.position = CGPointMake(self.frame.size.width/2 - 70, self.frame.size.height/2-2);
    fbToggleYes.name = @"fbyes";
    fbToggleYes.zPosition = 2;

    int hpBuffer = 40;
    int hpZ = 2;

    home = [SKSpriteNode spriteNodeWithTexture:home_texture];
    home.position = CGPointMake(hpBuffer, self.frame.size.height - hpBuffer);
    home.zPosition = hpZ;
    home.name = @"home";

    play = [SKSpriteNode spriteNodeWithTexture:play_texture];
    play.position = CGPointMake(self.frame.size.width - hpBuffer, self.frame.size.height - hpBuffer);
    play.zPosition = hpZ;
    play.name = @"play";

    [self addChild:bg];
    [self addChild:wbox];
    [self addChild:gamecenter];
    [self addChild:home];
    [self addChild:play];

    [self addChild:fbButton];
    [self addChild:fbToggleNo];

    [self addCredits];
    [self addStory];
}

-(void) addCredits{
    /* images */

    int cmbZ = wbox.zPosition + 1;
    int cmbY = wbox.position.y;
    int cmbXUnit = 132;
    int cmbX = self.frame.size.width/2 - (3*cmbXUnit)/2 + 20;
    int cmbWidth = 40;

    chance  = [SKSpriteNode spriteNodeWithTexture:chance_texture];
    max = [SKSpriteNode spriteNodeWithTexture:max_texture];
    bryce  = [SKSpriteNode spriteNodeWithTexture:bryce_texture];

    chance.zPosition = cmbZ;
    max.zPosition = cmbZ;
    bryce.zPosition = cmbZ;

    chance.position = CGPointMake(cmbX+cmbXUnit*0, cmbY+3);
    max.position = CGPointMake(cmbX+cmbXUnit*1 + 10, cmbY);
    bryce.position = CGPointMake(cmbX+cmbXUnit*2 + 10, cmbY+5);

    chance.size = CGSizeMake(cmbWidth, (chance.size.height/chance.size.width)*cmbWidth);
    max.size = CGSizeMake(cmbWidth, (max.size.height/max.size.width)*cmbWidth);
    bryce.size = CGSizeMake(cmbWidth, (bryce.size.height/bryce.size.width)*cmbWidth);

    [self addChild:chance];
    [self addChild:max];
    [self addChild:bryce];

    /* names */

    int cmb_nameXUnit = 30;
    int cmb_nameY = wbox.position.y - 10;
    int cmb_nameFontSize = 18;

    chance_name = [SKLabelNode labelNodeWithFontNamed:@"BebasNeue"];
    max_name = [SKLabelNode labelNodeWithFontNamed:@"BebasNeue"];
    bryce_name = [SKLabelNode labelNodeWithFontNamed:@"BebasNeue"];

    chance_name.text = @"Chance Daniel";
    max_name.text = @"Max Hudson";
    bryce_name.text = @"Bryce Daniel";

    chance_name.fontColor = [SKColor blackColor];
    max_name.fontColor = [SKColor blackColor];
    bryce_name.fontColor = [SKColor blackColor];

    chance_name.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeLeft;
    max_name.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeLeft;
    bryce_name.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeLeft;

    chance_name.position = CGPointMake(chance.position.x + cmb_nameXUnit, cmb_nameY);
    max_name.position = CGPointMake(max.position.x + cmb_nameXUnit, cmb_nameY);
    bryce_name.position = CGPointMake(bryce.position.x + cmb_nameXUnit, cmb_nameY);

    chance_name.fontSize = cmb_nameFontSize;
    max_name.fontSize = cmb_nameFontSize;
    bryce_name.fontSize = cmb_nameFontSize;

    chance_name.zPosition = cmbZ;
    max_name.zPosition = cmbZ;
    bryce_name.zPosition = cmbZ;

    [self addChild:chance_name];
    [self addChild:max_name];
    [self addChild:bryce_name];

    /* roles */

    int cmb_roleY = wbox.position.y - 25;
    int cmb_roleFontSize = 11;

    chance_role = [SKLabelNode labelNodeWithFontNamed:@"BebasNeue"];
    max_role = [SKLabelNode labelNodeWithFontNamed:@"BebasNeue"];
    bryce_role = [SKLabelNode labelNodeWithFontNamed:@"BebasNeue"];

    chance_role.text = @"Programmer";
    max_role.text = @"Programmer";
    bryce_role.text = @"Graphic Designer";

    chance_role.fontColor = [SKColor darkGrayColor];
    max_role.fontColor = [SKColor darkGrayColor];
    bryce_role.fontColor = [SKColor darkGrayColor];

    chance_role.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeLeft;
    max_role.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeLeft;
    bryce_role.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeLeft;

    chance_role.position = CGPointMake(chance.position.x + cmb_nameXUnit + 19, cmb_roleY);
    max_role.position = CGPointMake(max.position.x + cmb_nameXUnit + 12, cmb_roleY);
    bryce_role.position = CGPointMake(bryce.position.x + cmb_nameXUnit + 6, cmb_roleY);

    chance_role.fontSize = cmb_roleFontSize;
    max_role.fontSize = cmb_roleFontSize;
    bryce_role.fontSize = cmb_roleFontSize;

    chance_role.zPosition = cmbZ;
    max_role.zPosition = cmbZ;
    bryce_role.zPosition = cmbZ;

    [self addChild:chance_role];
    [self addChild:max_role];
    [self addChild:bryce_role];

    /* twitter handles */

    int cmb_handY = wbox.position.y - 40;
    int cmb_handFontSize = 10;

    chance_handle = [SKLabelNode labelNodeWithFontNamed:@"BebasNeue"];
    max_handle = [SKLabelNode labelNodeWithFontNamed:@"BebasNeue"];
    bryce_handle = [SKLabelNode labelNodeWithFontNamed:@"BebasNeue"];

    chance_handle.text = @"@ChanceOfThat";
    max_handle.text = @"@max_hud";
    bryce_handle.text = @"@BryceOfLife";

    chance_handle.fontColor = [SKColor darkGrayColor];
    max_handle.fontColor = [SKColor darkGrayColor];
    bryce_handle.fontColor = [SKColor darkGrayColor];

    chance_handle.position = CGPointMake(chance.position.x, cmb_handY);
    max_handle.position = CGPointMake(max.position.x, cmb_handY);
    bryce_handle.position = CGPointMake(bryce.position.x, cmb_handY);

    chance_handle.fontSize = cmb_handFontSize;
    max_handle.fontSize = cmb_handFontSize;
    bryce_handle.fontSize = cmb_handFontSize;

    chance_handle.zPosition = cmbZ;
    max_handle.zPosition = cmbZ;
    bryce_handle.zPosition = cmbZ;

    [self addChild:chance_handle];
    [self addChild:max_handle];
    [self addChild:bryce_handle];

    /* touchzones */

    CGSize cmdL_size = CGSizeMake(120, 70);
    SKColor *cmdL_color = [SKColor clearColor];
    int cmdLZ = 3;
    int cmdLX = cmbX + 40;

    chance_link = [SKSpriteNode spriteNodeWithColor:cmdL_color size:cmdL_size];
    max_link = [SKSpriteNode spriteNodeWithColor:cmdL_color size:cmdL_size];
    bryce_link = [SKSpriteNode spriteNodeWithColor:cmdL_color size:cmdL_size];

    chance_link.position = CGPointMake(cmdLX+cmbXUnit*0, cmbY);
    max_link.position = CGPointMake(cmdLX+cmbXUnit*1 + 10, cmbY);
    bryce_link.position = CGPointMake(cmdLX+cmbXUnit*2 + 10, cmbY);

    chance_link.zPosition = cmdLZ;
    max_link.zPosition = cmdLZ;
    bryce_link.zPosition = cmdLZ;

    chance_link.name = @"c_handle";
    max_link.name = @"m_handle";
    bryce_link.name = @"b_handle";

    [self addChild:chance_link];
    [self addChild:max_link];
    [self addChild:bryce_link];
}

-(void) addStory{

    int stX = self.frame.size.width/2;
    int stZ = 2;
    SKColor *stColor = [SKColor whiteColor];

    story1 = [SKLabelNode labelNodeWithFontNamed:@"BebasNeue"];
    story2 = [SKLabelNode labelNodeWithFontNamed:@"BebasNeue"];
    story3 = [SKLabelNode labelNodeWithFontNamed:@"BebasNeue"];

    story1.text = @"Gon";
    story2.text = @"Help Gon-Gon and his friends get";
    story3.text = @"Back to the time they came from!";

    story1.fontColor = stColor;
    story2.fontColor = stColor;
    story3.fontColor = stColor;

    story1.zPosition = stZ;
    story2.zPosition = stZ;
    story3.zPosition = stZ;

    story1.position = CGPointMake(stX, self.frame.size.height - 55);
    story1.fontSize = 50;

    story2.position = CGPointMake(stX, self.frame.size.height - 95);
    story2.fontSize = 30;

    story3.position = CGPointMake(stX, self.frame.size.height - 120);
    story3.fontSize = 20;

    [self addChild:story1];
    [self addChild:story2];
    [self addChild:story3];
}

-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    UITouch *touchUI = [touches anyObject];
    CGPoint touchPoint = [touchUI locationInNode:self];
    SKNode *touchNode = [self nodeAtPoint:touchPoint];

    if([touchNode.name isEqualToString:@"home"]){
        StartViewController *svc = [[StartViewController alloc] initWithSize:self.size];
        SKTransition *fade = [SKTransition fadeWithColor :[SKColor blackColor] duration:0.4];
        [self.view presentScene:svc transition:fade];
    }

    if([touchNode.name isEqualToString:@"play"]){
        gameViewController *gvc = [[gameViewController alloc] initWithSize:self.size];
        SKTransition *fade = [SKTransition fadeWithColor :[SKColor blackColor] duration:0.4];
        [self.view presentScene:gvc transition:fade];
    }

    if([touchNode.name isEqualToString:@"gc"]){
        NSDictionary * dict = [[NSDictionary alloc]initWithObjectsAndKeys:[NSNumber numberWithBool:1], @"showGC", nil];

        [[NSNotificationCenter defaultCenter]postNotificationName:@"kNotificationUpdateBannerView" object:self userInfo:dict];
    }

    if([touchNode.name isEqualToString:@"c_handle"]){
        NSURL *urlApp = [NSURL URLWithString: [NSString stringWithFormat:@"%@", @"twitter:///user?screen_name=ChanceOfThat"]];
        int worked = [[UIApplication sharedApplication] openURL:urlApp];
        if(!worked){
            NSURL *urlApp = [NSURL URLWithString: [NSString stringWithFormat:@"%@", @"https://twitter.com/#!/ChanceOfThat"]];
            [[UIApplication sharedApplication] openURL:urlApp];
        }
    }

    if([touchNode.name isEqualToString:@"m_handle"]){
        NSURL *urlApp = [NSURL URLWithString: [NSString stringWithFormat:@"%@", @"twitter:///user?screen_name=max_hud"]];
        int worked = [[UIApplication sharedApplication] openURL:urlApp];
        if(!worked){
            NSURL *urlApp = [NSURL URLWithString: [NSString stringWithFormat:@"%@", @"https://twitter.com/#!/max_hud"]];
            [[UIApplication sharedApplication] openURL:urlApp];
        }
    }

    if([touchNode.name isEqualToString:@"b_handle"]){
        NSURL *urlApp = [NSURL URLWithString: [NSString stringWithFormat:@"%@", @"twitter:///user?screen_name=BryceOfLife"]];
        int worked = [[UIApplication sharedApplication] openURL:urlApp];
        if(!worked){
            NSURL *urlApp = [NSURL URLWithString: [NSString stringWithFormat:@"%@", @"https://twitter.com/#!/BryceOfLife"]];
            [[UIApplication sharedApplication] openURL:urlApp];
        }
    }
}

@end
4

5 に答える 5

19

この質問をした人も同様の問題に直面していました。

彼がそれを解決できたかどうか尋ねられたとき、彼らは次のように言いました:

はい、そうしました。シーンやスプライト キットからできることは何もありませんでした。シーンとそれを含むビューを親ビューから完全に削除し、他のビューとのすべての結合を切断するだけで済みました。メモリの割り当ても解除するために、システムの一部。

シーンごとに個別のビューを使用し、これらのビュー間の遷移を行う必要があります。次の手順に従って、自然に見えるようにすることができます。

1 - あるシーンから別のシーンに移行したい時点で、次のコードを使用してシーンのスナップショットを取得します。

UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, NO, scale);
[self drawViewHierarchyInRect:self.bounds afterScreenUpdates:YES];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

次に、この画像を現在のシーンの SKView のサブビューとして追加し、シーンを削除します。

2 - 別のビューで新しいシーンを初期化し、UIView アニメーションを使用して 2 つのビュー間を移行します。

3 - スーパービューから最初のビューを削除します。

于 2014-03-20T09:20:23.720 に答える
7

Swift で SpriteKit を使い始めたばかりで、同じ問題がありました。イントロ シーンで、メイン メニュー シーンに移行した後に停止したい音楽を再生していましdeinitAVAudioPlayer.stop()。 、しかし、deinit呼び出されたことはありませんでした。

周りを見回した後、シーンへのいくつかの強い参照が原因である可能性があることがわかったので、GameViewController:UIViewControllerサブクラスで次のコードを変更しました。

let intro = IntroScene(size: skView.bounds.size)
skView.presentScene(intro)

skView.presentScene(IntroScene(size: skView.bounds.size))

そしてイントロのシーンで割り切られたくて、

let mainMenu  = MainMenuScene(size: self.size)
let crossFade = SKTransition.crossFadeWithDuration(1)

self.scene.view.presentScene(mainMenu, transition: crossFade)

self.scene.view.presentScene(MainMenuScene(size: self.size),
                             transition: SKTransition.crossFadeWithDuration(1))

そしてそれはうまくいきました!遷移が完了した後、deinitメソッドが呼び出されました。

発信シーンへの参照を保持する変数があったため、発信シーンは初期化されていなかったと思います。

于 2014-06-12T15:39:44.350 に答える
2

2019年12月/Swift 5

アップデート:

私のレイアウト:

2つのSKViewを含む単一のView Controllerがありますそれぞれが同時に提示される独自の SKScene を持っています。1 つの SKView とその SKScene は、プレイヤー キャラクターのレンダリング、制御、NPC のレンダリング、カメラ トラッキング、シバン全体などを行うメイン オーバーワールドであり、もう 1 つの SKView とその SKScene は、オーバーワールドのミニ マップを表示します。また、かなりの数の SKSpriteNode があり、それらの多くには常に何らかの種類の SKAction/アニメーションがノンストップで実行されていることが想像できます (たとえば、揺れる木)。私の SKScenes には、キャラクター ノード、建物ノード、ツリー ノードなど、SKSpriteNodes の特定のグループを指す独自の配列も含まれています。これは、迅速なアクセスと利便性を目的としています。さらに、SKTextures の配列またはキャラクター モデルなどを含むシングルトンがいくつかあります。それらは、何かが必要になるたびにディスクから読み取ったりストレージにアクセスしたりするのではなく、迅速なデータアクセスの最適化として保持されています。ビュー コントローラー内のゲーム UI に使用される UIKit 要素さえあります。キャラクター、建物、ゲーム セッション全体のデータを含む私のモデルなど、他の多くのオブジェクトにはすべて、誰かを指しているある種のデリゲートがあります。これらすべてに加えて、コードベースは膨大です。

デバッグセッションでメモリを観察した後、何も保持されていないことを確認する確実な方法は、次のことを絶対に確認することであることがわかりました。

メモリ処理:

  • シーンのプレゼンテーションに nil を渡し、その skview のプロパティ/ポインターも nil に設定します
  • すべてのView Controllerプライマリビューサブビューを削除します
  • あなたが持っているすべての デリゲートを絶対にゼロに設定してください!!!!!!!!!!!!!!
  • オブザーバーがいる場合はすべて削除します
  • あなたが作成したある種のオブジェクトへの配列/辞書またはポインターがある場所ならどこでも、それをnil/空に設定します
  • CRITICAL : 上記のすべてを単一の関数/メソッドに入れて、View Controller を変更する直前に呼び出すようにしてください!

*注: アプリ全体で 1 つのビュー コントローラーを使用している場合 (すべてをスクイーズできたことをお祝いします - オーバーロード スクイーザー)、すべてを nil にしないでください。注意が必要です。ただし、プレゼンテーション中は前のシーンを nil に設定する必要があります。

ビューコントローラー間をジャンプする場合は、次のようになります。

/// Remove all pointers to any data, nodes & views.
fileprivate func cleanUp() {
    guard self.skView != nil else { return }
    // Session was passing data updates to this view controller; time to nil it
    self.gameSessionModel.delegate = nil
    self.skView.presentScene(nil)
    self.skViewMiniMap.presentScene(nil)
    self.skView = nil
    self.skViewMiniMap = nil
    for subview in self.view.subviews {
        subview.removeFromSuperview()
    }
}

/// Take the user back to the main menu module/view controller.
fileprivate func handleMenuButton() {
    // First, clean up everything
    self.cleanUp()
    // Then go to the other view controller
    let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
    let vc = storyboard.instantiateViewController(withIdentifier: "MainViewController")
    self.show(view, sender: .none)
}

handleMenuButton()関数または別のView Controllerを表示するために使用する関数を呼び出しますが、cleanUp()関数がその中で呼び出されることを確認してください! *注: 「gameSessionModel」などのクラスは、完全に私自身のカスタム クラスです。Xcodeはそのようなものでエラーをスローします(魔法のように同じものを持っていない限り...)ので、そのようなものを削除してください。これらは、現在のビュー コントローラーを指しているデリゲートがある場合のサンプル コードとしてのみ使用されます。

単一の SKView で異なる SKScene のみを提示している場合、cleanUp()関数は次のように「より軽量」になる可能性があります。

/// Remove all pointers to any data, nodes & views.
fileprivate func cleanUp() {
    self.skView.presentScene(nil)
    // Previous scene was set to nil, its deinit called. Now onto the new scene:
    let gameScene = self.setupGameScene(id: "perhapsYouUseStringIDsToDisntiguishBetweenScenes?")
    self.skView.presentScene(gameScene)
}

*注: SKScene のdeinitメソッドを使用して不要なものを削除することを忘れないでください。見逃した可能性のあるものを解きほぐすために、すべてのクラスで常に使用している練習です。

于 2019-12-01T14:33:24.677 に答える
0

編集: NSTimer に関する私の以前の考えは無関係でした

これがこのシーンだけの問題であることを確認するには、(このシーンを含む) すべてのシーンの dealloc メソッドを次のようにオーバーライドします。

 -(void)dealloc {
  NSLog(@"Dealloc <scene name>");
 }

他のシーン トランジションを見て、それらが適切に割り当て解除されているかどうかを確認します。これらのシーンの違いを見つけてください。これは、それが孤立した問題なのか、より大きな問題なのかを確認するのに役立ちます。問題が解決したら、実際にメモリの割り当てを解除するメソッドをオーバーライドしているため、dealloc メソッドをコメント アウトするか削除してください。うまくいけば、これが役に立ちます!

于 2014-03-18T16:14:58.520 に答える
0

私が見る限り、SKSceneまたはSKViewに問題はありません。シーン インスタンスが他の場所、特にブロック内で強く参照されていないことを確認してください。ブロックは無視される可能性が非常に高いです。

ブロック内の弱い参照の詳細: https://stackoverflow.com/a/17105368/571489

私が見る限り、シーン インスタンスを強く参照するブロックがあります。

[SKTexture preloadTextures:to_preload withCompletionHandler:^{
    [self fadeRemove:masterOverlay];
    [self initialize];
}];
于 2016-09-23T14:17:02.067 に答える