【发布时间】:2025-11-23 21:40:01
【问题描述】:
这是一个带有 iOS 8.0+ 目标的 Swift 2.1 项目。
很像this question 中的用户 Cybermew,我有一个 A->B->C->D 的设置。 A 是一个导航控制器,其余的是常规的 UIViewControllers。当从 D 展开到 B 时,C 不会被释放。这会导致内存泄漏和其他意想不到的副作用。
与上面链接的问题相反,我没有任何我知道的 NSTimer 可能会将视图保留在内存中。什么可能导致这种情况发生?
C 代码(修剪):
import UIKit
import SpriteKit
import AVFoundation
import AVFoundation.AVAudioSession
class GameViewController: UIViewController {
var scene: GameScene!
var level: Level!
@IBOutlet weak var gameOverPanel: UIImageView!
@IBOutlet weak var heroPicture: UIImageView!
@IBOutlet weak var villainPicture: UIImageView!
@IBOutlet weak var spellOneButton: UIButton!
@IBOutlet weak var doubleLife: UISwitch!
let attackSound = SKAction.playSoundFileNamed("Attack.wav", waitForCompletion: false)
var tapGestureRecognizer: UITapGestureRecognizer!
var backgroundMusic: AVAudioPlayer = {
let sess = AVAudioSession.sharedInstance()
if sess.otherAudioPlaying {
_ = try? sess.setCategory(AVAudioSessionCategoryAmbient, withOptions: [])
_ = try? sess.setActive(true, withOptions: [])
}
let url = NSBundle.mainBundle().URLForResource("BackgroundMusic", withExtension: "mp3")
let player = try? AVAudioPlayer(contentsOfURL: url!)
player!.numberOfLoops = -1
return player!
}()
override func prefersStatusBarHidden() -> Bool {
return true
}
override func shouldAutorotate() -> Bool {
return true
}
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.AllButUpsideDown
}
override func viewDidLoad() {
super.viewDidLoad()
let skView = view as! SKView
skView.multipleTouchEnabled = false
scene = GameScene(size: skView.bounds.size)
scene.scaleMode = .AspectFill
level = Level(filename: "Level_0")
scene.level = level
scene.addTiles()
scene.swipeHandler = handleSwipe
skView.presentScene(scene)
backgroundMusic.play()
beginGame()
}
}
从聊天移到这里:
swipeHandler 声明为:
var swipeHandler: ((Swap) -> ())?
而交换是:
struct Swap: CustomStringConvertible, Hashable {
// blabla
}
如果在GameViewController 上调用它,则一旦填充了交换:
func handleSwipe(swap: Swap) {
view.userInteractionEnabled = false
if level.isPossibleSwap(swap) {
level.performSwap(swap)
scene.animateSwap(swap, completion: handleMatches)
} else {
scene.animateInvalidSwap(swap) {
self.view.userInteractionEnabled = true
}
}
【问题讨论】:
-
C 是否包含对 B 的强引用?
-
不幸的是它没有。
-
C 是如何创建的?你能发布 C 的代码吗?
-
描述已更新。我删除了一些占用大量空间并且很可能无关紧要的部分(变量的初始化)。
-
尝试注释掉部分代码,减少功能,直到找到罪魁祸首。尝试先注释掉提供和播放背景音乐的代码。