gpt4 book ai didi

ios - 无法使用 Xcode Instruments 定位内存泄漏

转载 作者:行者123 更新时间:2023-11-28 20:54:13 28 4
gpt4 key购买 nike

问题

我之前发现我的游戏内存使用量只有在移动方 block 时才会上升,但它再也不会下降。由此,我可以判断存在内存泄漏。

然后我开始使用 Xcode Instruments,我对它还很陌生。所以我从this article关注了很多事情,尤其是 Recording Options,然后我将模式设置为显示 Call Tree

仪器结果

Instruments - Results of testing for leaks

我需要什么帮助?

我有两个函数,它们只是沿着该行/列移动所有图 block ,然后在最后克隆图 block (使用 node.copy()),这样一切都可以“循环”,因此项目名称。

我觉得好像磁贴克隆可能会导致一些保留周期,但是,它存储在函数范围内的变量中。在克隆体上运行 SKAction 后,我使用 copiedNode.removeFromParent() 从场景中删除了该图 block 。

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


代码

我已将这段代码缩短到我认为必要的程度。

类顶部的声明:

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

在移动方 block 函数中克隆方 block :

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

立即移动方 block 的函数:

/// 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 数组中删除了克隆的图 block 引用。


泄漏发生的大致位置(由 Mark Szymczyk 提供帮助)

这是我在调用堆栈中双击移动瓷砖函数后发生的事情(引用下面他的回答):

Instruments - Finding the memory leak

这证实了内存泄漏是由节点克隆以某种方式引起的,但我仍然不知道为什么这个节点从 cloneTiles 数组和场景中删除后仍然保留.节点是否由于某种原因无法从场景中移除?

请留下任何关于此的提示或问题,以便解决此问题!

更多调查

我现在一直在努力掌握 Xcode Instruments,但我仍然很难找到这个内存泄漏。这是泄漏面板,可能会有所帮助:

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 属性,因为它总是立即为 nil,并且 unowned 导致有关在释放后读取引用的崩溃。如果有帮助,这里还有 Cycles & Roots 图:

Instruments - Cycles & Roots graph


感谢您的帮助!

最佳答案

我很怀疑你管理复制节点的方式;您可能过早地释放了它,只有保留周期阻止您发现这个错误。但是,让我们专注于打破保留周期。

您要做的是使进入操作方法的所有内容都,这样操作方法就不会进行强捕获。然后在操作方法中,您希望立即保留那些弱引用,这样它们就不会从您的下面消失。这就是所谓的“弱强之舞”。像这样:

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

关于ios - 无法使用 Xcode Instruments 定位内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54392245/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com