2014-07-07 5 views
1

Я создаю игру в комплекте спрайтов с помощью swift и столкнулся с проблемой. У меня есть два контроллера вида, каждый из которых имеет одну сцену и один переход к другому. Все это работает отлично в первый раз, но затем, когда я вернусь к первому контроллеру представления, а затем снова перейду ко второму, я использую двойную память. Это создает у меня впечатление, что ничего не освобождается, но объекты перераспределяются каждый раз, когда я перехожу на сцену. Я запустил приложение в инструментах и ​​получил тот же результат. В приведенном ниже изображении я переместился из одной сцены в другую, а затем снова вернулся к первому, и все же он, похоже, перераспределяет первую сцену и все же не очищает память. Поскольку метод dealloc не используется сейчас, я не вижу, как я могу это исправить. Я отправлю код на первый контроллер представления ниже, чтобы вы могли посмотреть на него. Большое спасибо.Deallocate SKScene после модального перехода

Instument's recordings

import UIKit 
import SpriteKit 

class SelectionViewController: UIViewController { 

var selectionScene:SelectionScene? 
var currentRocketName = "" 

@IBOutlet var playButton: UIButton 

override func viewDidLoad() { 
    super.viewDidLoad() 

    if let selectionScene = SelectionScene.unarchiveFromFile("SelectionScene") as? SelectionScene { 

     // Configure the view. 
     let skView = self.view as SKView 
     skView.showsFPS = true 
     skView.showsNodeCount = true 
     skView.multipleTouchEnabled = false 

     /* Sprite Kit applies additional optimizations to improve rendering performance */ 
     skView.ignoresSiblingOrder = true 

     /* Set the scale mode to scale to fit the window */ 
     selectionScene.scaleMode = .ResizeFill 
     selectionScene.viewController = self 

     skView.presentScene(selectionScene) 

     NSNotificationCenter.defaultCenter().addObserver(selectionScene, selector: "spinnerChanged", name: "spinnerValueChanged", object: nil) 
     NSNotificationCenter.defaultCenter().addObserver(selectionScene, selector: "productBought", name: "ProductBought", object: nil); 
     NSNotificationCenter.defaultCenter().addObserver(selectionScene, selector: "manageErrorInPurchase", name: "ErrorOccured", object: nil) 

    } 
} 

override func shouldAutorotate() -> Bool { 
    return true 
} 

override func viewDidAppear(animated: Bool) { 
} 

@IBAction func playButtonPressed(sender: UIButton) { 
    self.performSegueWithIdentifier("moveToGame", sender: nil) 
} 

override func prefersStatusBarHidden() -> Bool { 
    return true 
} 

override func supportedInterfaceOrientations() -> Int { 
    if UIDevice.currentDevice().userInterfaceIdiom == .Phone { 
     return Int(UIInterfaceOrientationMask.AllButUpsideDown.toRaw()) 
    } else { 
     return Int(UIInterfaceOrientationMask.All.toRaw()) 
    } 
} 

override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
    // Release any cached data, images, etc that aren't in use. 
} 

override func viewDidUnload() { 
    NSNotificationCenter.defaultCenter().removeObserver(selectionScene) 
} 

override func viewDidDisappear(animated: Bool) { 
    NSNotificationCenter.defaultCenter().removeObserver(selectionScene) 
} 

override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) { 
    if segue.identifier == "moveToGame" { 
     let destController = segue.destinationViewController as GameViewController 
     destController.rocketTexture = SKTexture(imageNamed: self.currentRocketName) 
    } 
} 

} 

selectionScene Оба и currentRocketName передаются ViewController как только они загружены в поле зрения

ответ

4

Я не знаком с Swift, поэтому я дам вам примеры в Objective-C.

Создайте IBOutlet для skView. Когда вы собираетесь представить другой ViewController, удалить skView от его SuperView и ноль это:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 
    // Need to deallocate GameScene (if game is not paused) 
    [self.skView removeFromSuperview]; 
    self.skView = nil; 
    .... 
} 

Не забудьте добавить skView назад к мнению ViewController годов, когда ViewController становится загружен:

if (!self.skView.window) { 
    [self.view addSubview:self.skView]; 
} 

чтобы легко проверить, если SKScene было высвобождены или нет, добавьте этот метод к нему:

- (void)dealloc { 
    NSLog(@"GAME SCENE DEALLOCATED"); 
} 
+0

Очень тщательный ответ, и за исключением метода dealloc, который не может быть использован с iOS8 и быстры, все остальное выглядит, как он будет работать в совершенстве. –

+0

Я еще не встречал Swift :) –

+1

@JackC вы, вероятно, захотите использовать 'deinit' вместо' dealloc' с Swift: https://developer.apple.com/library/prerelease/mac/documentation/Swift/Conceptual /Swift_Programming_Language/Deinitialization.html#//apple_ref/doc/uid/TP40014097-CH19 –

0

у меня был подобный I СГУП.

Оказывается, я создал сильную ссылку, имея экземпляр SKScene в качестве делегата в другом классе. После объявления каждое свойство типа SKScene или типа UIView как слабый мой вопрос был решен:

weak var skScene:SKScene! 
Смежные вопросы