簡體   English   中英

使用Xcode Instruments無法定位內存泄漏

[英]Unable to locate memory leak using Xcode Instruments

問題

較早時,我發現游戲中的內存使用量僅在移動磁貼時才增加,但再也沒有回落。 由此,我可以判斷出內存泄漏。

然后,我開始使用Xcode Instruments,這是我的新手。 因此,我遵循了本文中的許多內容,尤其是“ Recording Options ,然后設置了顯示“ Call Tree的模式。

儀器結果

儀器-泄漏測試結果

我需要什么幫助?

我有兩個函數,它們僅沿着該行/列移動所有node.copy()貼,然后在末尾克隆node.copy()貼(使用node.copy() ),以便所有內容都可以“循環播放”,因此是項目名稱。

我覺得瓦片克隆可能會導致某些保留周期,但是它存儲在函數范圍內的變量中。 在克隆上運行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數組中刪除了克隆的tile引用,所以不知道為什么它存在於此代碼中。


大概發生泄漏的位置(由Mark Szymczyk幫助)

這是我雙擊調用堆棧中的move tile函數后發生的情況(請參見下面的答案):

儀器-查找內存泄漏

這可以確認內存泄漏是由節點克隆以某種方式引起的,但是我仍然不知道為什么在從cloneTiles數組和場景中刪除該節點后仍保留該節點。 節點是否可能由於某種原因而無法從場景中移除?

請留下任何有關此的提示或問題,以便可以解決此問題!

更多調查

我現在一直在嘗試與Xcode Instruments接觸,但是我仍然真的很難找到這種內存泄漏。 這是泄漏面板,可能會有所幫助:

儀器-泄漏面板

樂器-泄漏的歷史

即使嘗試過[weak self] ,我仍然沒有運氣:

工具-在閉包內使用[弱自我]

甚至在閉包內的[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調用樹中雙擊moveHorizontally條目,則Instruments將向您顯示分配泄漏內存的代碼行。 窗口底部是“呼叫樹”按鈕。 如果單擊該按鈕,則可以反轉調用樹並隱藏系統庫。 這樣做將使在調用樹中查找代碼更加容易。

您可以在以下文章中了解有關Instruments的更多信息:

使用儀器評估應用程序的內存使用情況

我對您管理復制節點的方式非常懷疑; 您可能會過早釋放它,並且只有保留周期才阻止您發現此錯誤。 但是,讓我們集中精力打破保留周期。

您想要做的是使進入該動作方法的所有內容都變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
        }
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM