【问题标题】:Release nested Scripting.Dictionary with RemoveAll()使用 RemoveAll() 释放嵌套的 Scripting.Dictionary
【发布时间】:2012-12-19 02:14:01
【问题描述】:

我在这里找到了可以回答一半问题的主题: Does Scripting.Dictionary's RemoveAll() method release all of its elements first?

在我的例子中,值是字典的实例,所以我有字典对象的嵌套层次结构。

我的问题是我是否需要在每个子词典上调用 RemoveAll?

' just for illustration
Dim d As Dictionary
Set d = New Dictionary

Set d("a") = New Dictionary
Set d("b") = New Dictionary

' Are the next section of code necessary?
' -------------------- section start
Dim key As Variant
For Each key In d
    d.Item(key).RemoveAll
Next
' -------------------- section end

d.RemoveAll
Set d = Nothing

【问题讨论】:

  • 必要是什么意思?你想完成什么?
  • 我想释放所有对象,正如我所读(在上面的主题中),RemoveAll 将所有对象设置为 Nothing,非常好,但不确定该函数是否是递归的。

标签: syntax dictionary vb6 removeall


【解决方案1】:

在 VB6 中,所有对象(通过 COM)都受到引用计数,因此,除非有循环,否则您不需要手动处理。

【讨论】:

    【解决方案2】:

    考虑这段代码

    Option Explicit
    
    Private m_cCache As Collection
    
    Private Sub Form_Load()
        ' just for illustration
        Dim d As Dictionary
        Set d = New Dictionary
    
        Set d("a") = New Dictionary
        Set d("b") = New Dictionary
    
        d("b").Add "c", 123
        SomeMethod d
    
        ' Are the next section of code necessary?
        ' -------------------- section start
        Dim key As Variant
        For Each key In d
            d.Item(key).RemoveAll
        Next
        ' -------------------- section end
    
        d.RemoveAll             '--- d("b") survives
        Set d = Nothing         '--- d survives
    
        Debug.Print "main="; m_cCache("main").Count, "child="; m_cCache("child").Count
    End Sub
    
    Private Sub SomeMethod(d As Dictionary)
        Set m_cCache = New Collection
    
        m_cCache.Add d, "main"
        m_cCache.Add d("b"), "child"
    End Sub
    

    如果不进行清理,则 d("b") 部分几乎不会受到影响——既不会删除子项,也不会终止实例。

    【讨论】:

    • 感谢您的回复。你在这里介绍的是关于清理多个引用,我知道,嗯......在我的情况下,没有对我的任何 Dictionary 对象的额外引用,但从这一点来看,也许你试图让我得出一个结论我应该在 d.RemoveAll 之前在 d("a") 和 d("b") 上调用 RemoveAll,即我需要包含我的代码部分?
    • 这取决于您存储在Dictionarys 中的参考类型。如果你有类似d("a").Add "main", d 的东西,这会带来一个循环引用,如果没有RemoveAll 调用就无法释放。如果您的清理部分是一个通用函数,最好明确使用RemoveAll,并以性能换取安全。
    【解决方案3】:

    好的,我想我可以通过下一个测试来回答自己。

    Sub Main()
      Dim d As Dictionary
      Dim i, j As Integer
      Dim sDummy As String * 10000
      For i = 1 To 1000
        Set d = New Dictionary      ' root dict.
        Set d("a") = New Dictionary ' child dict.
        For j = 1 To 1000
          d("a").Add j, sDummy
        Next j
        'd("a").RemoveAll
        d.RemoveAll
        Set d = Nothing
      Next i
    End Sub
    

    我注释掉了d("a").RemoveAll(我的儿童词典)并且没有任何内存泄漏。这意味着在根 (d) 上调用 RemoveAll 就足够了,这就是我需要知道的全部内容。

    【讨论】:

    • 我看不出你为什么需要在根级字典上调用RemoveAll。释放对它的最后一个引用应该自行完成。
    • 顺便说一句,我没有在你的代码中修复它,但在 VB6 中 Dim i, j As Integer 表示 Dim i As Object, j As Integer。
    • @MarkHurd - 感谢您提供有关 Dim i, j As Integer 的提示。由于我是 VB6 的新手,我认为这两个变量都是整数。再次感谢!
    猜你喜欢
    • 2010-09-09
    • 2015-11-02
    • 1970-01-01
    • 2022-10-14
    • 1970-01-01
    • 2010-10-13
    • 2019-06-06
    • 2012-11-02
    • 2010-11-26
    相关资源
    最近更新 更多