无法使用的Xcode仪器来定位内存泄漏

问题描述 投票:0回答:2

问题

我刚才发现,在我的游戏我的内存使用量只上升时,地砖被感动了,但它永远不会再回去了。由此,我可以告诉有内存泄漏。

然后我就开始使用的Xcode工具,这点我是很新的。所以我也跟着从this article很多东西,尤其是Recording Options,然后我将模式设置为显示Call Tree

仪器的结果

Instruments - Results of testing for leaks

我需要什么帮助?

我有两个功能,只是将所有的砖沿行/列,然后克隆(使用node.copy())结尾的瓷砖所以一切都可以“loopover”,因此该项目的名称。

我觉得好象瓦片克隆可能会造成一些保留周期,但是,它被存储在功能范围内的变量。我跑克隆上的SKAction后,我从现场使用copiedNode.removeFromParent()删除瓷砖。

那么,什么可能会导致此内存泄漏?我可能是找错了地方?


我已经缩短这段代码什么,我认为有必要。

声明在类的顶部:

/// Delegate to the game scene to reference properties.
weak var delegate: GameScene!
/// All the cloned tiles currently on the board.
private var cloneTiles = [SKSpriteNode]()

移动瓷砖职能范围内的瓷砖的克隆:

/// A duplicate of the current tile.
let copiedNode = currentTile.node.copy() as! SKSpriteNode // Create copy
cloneTiles.append(copiedNode) // Add as a clone
delegate.addChild(copiedNode) // Add to the scene
let copiedNodeAction = SKAction.moveBy(x: movementDifference, y: 0, duration: animationDuration) // Create the movement action

// Run the action, and then remove itself
copiedNode.run(copiedNodeAction) {
    self.cloneTiles.remove(at: self.cloneTiles.firstIndex(of: copiedNode)!)
    copiedNode.removeFromParent()
}

功能立即采取行动瓷砖:

/// Move all tiles to the correct location immediately.
private func moveTilesToLocationImmediately() {
    // Remove all clone tiles
    cloneTiles.forEach { $0.removeFromParent() }
    cloneTiles.removeAll()

    /* Moves tiles here */
}

有什么我需要声明的weak var什么?我知道发生周期如何挽留,但不知道为什么它在这段代码存在,因为我删除从cloneTiles阵列克隆平铺参考。


大致在泄漏发生(由Mark Szymczyk帮助)

这是发生了什么调用堆栈移动瓷砖功能我双击后(请参阅下面他的回答):

Instruments - Finding the memory leak

这是确认内存泄漏是由节点克隆不知何故造成的,但我仍然不知道为什么它是从cloneTiles阵列和现场取出后,该节点仍然被保留。可以在节点是从现场由于某些原因得到清除有问题?

请留下这方面有任何建议或疑问,所以这个问题是可以解决的!

更多调查

现在我一直在试图让在Xcode工具交手,但我还是很努力寻找此内存泄漏。这里是泄漏面板可以帮助:

Instruments - Leaks panel

Instruments - Leak's history

即使试图[weak self]后,我仍然没有运气:

Instruments - Using [weak self] within the closure

即使泄漏的历史看起来仍然与封闭内[weak self]相同。

继续尝试解决参考周期

目前,@matt帮助我解决这个问题。我已经改变了几行代码,通过增加之类的东西[unowned self]

// Determine if the tile will roll over
if direction == .up && movementDifference < 0 || direction == .down && movementDifference > 0 {
    // Calculate where the clone tile should move to
    movementDifference -= rollOverDistance

    /// A duplicate of the current tile.
    let copiedNode = currentTile.node.copy() as! SKSpriteNode // Create copy
    cloneTiles.append(copiedNode) // Add as a clone
    delegate.addChild(copiedNode) // Add to the scene
    let copiedNodeAction = SKAction.moveBy(x: 0, y: movementDifference, duration: animationDuration) // Create the movement action

    // Run the action, and then remove itself
    copiedNode.run(copiedNodeAction) { [unowned self, copiedNode] in
        self.cloneTiles.remove(at: self.cloneTiles.firstIndex(of: copiedNode)!).removeFromParent()
    }

    // Move the original roll over tile back to the other side of the screen
    currentTile.node.position.y += rollOverDistance
}

/// The normal action to perform, moving the tile by a distance.
let normalNodeAction = SKAction.moveBy(x: 0, y: movementDifference, duration: animationDuration) // Create the action
currentTile.node.run(normalNodeAction) { [unowned self] in // Apply the action
    if forRow == 1 { self.animationsCount -= 1 } // Lower animation count for completion
}

不幸的是,我不能让copiedNode一个weak财产,因为这将永远是瞬间nilunowned所引起的释放后被看了一则关于参考崩溃。这里也是Cycles & Roots图,如果这是有帮助的:

Instruments - Cycles & Roots graph


感谢您的任何帮助!

ios xcode memory-management memory-leaks xcode-instruments
2个回答
1
投票

我是非常可疑的你管理拷贝节点的方式;你可能会过早地释放它,只有保留周期阻止你发现这个错误。然而,让我们集中精力打破保留周期。

你想要做的就是让一切都进入操作方法weak,因此没有强烈的捕获由操作方法。然后在操作方法要立即保留这些弱引用,使他们不从你下了消失。这就是所谓的“弱强舞”。像这样:

    copiedNode.run(copiedNodeAction) { [weak self, weak copiedNode] in
        if let `self` = self, let copiedNode = copiedNode {
            // do stuff here
            // be sure to log so you know we arrived here at all, as we might not
        }
    }

1
投票

我可以帮上仪器前一点点。如果您双击该仪器的moveHorizontally入口调用树,仪器会显示您的代码被分配泄漏的内存的线。在窗口的底部是一个调用树按钮。如果你点击,你可以反调用树和隐藏系统库。否则,这将使它更容易找到调用树代码。

您可以了解更多关于仪器下面的文章中:

Measuring Your App's Memory Usage with Instruments

© www.soinside.com 2019 - 2024. All rights reserved.