当静态变量被释放时swift

时间:2017-08-30 09:34:38

标签: swift

我想知道何时释放static变量,所以我创建如下:

class A {
    init() {
        print("A init")
    }

    deinit {
        print("A deinit")
    }
}

class B {
    static let a = A()

    deinit {
        print("B deinit")
    }

    init() {
        print("B init")
    }
}

var b: B? = B()
B.a
b = nil

变量a' s deinit被调用?如果b = nil,则A' s deinit未被调用。

4 个答案:

答案 0 :(得分:8)

只有当没有其他东西对它有强烈的引用时,对象才会被取消初始化。

在您的情况下,b 持有对a的引用。班级B

b设置为nil对a无效,因为b从未对a进行过引用。 b基本上无关紧要。 ab是不相关的对象。

现在我们知道 B持有对a的引用,我们能否以某种方式销毁类B以便a可以取消初始化?答案是不。 a就像全局范围内的变量。 a只会在程序停止时取消初始化。

使一些东西得到去初始化的另一种方法是通过设置对它的所有引用来引用其他东西。但由于在这种情况下a声明为let,因此您无法真正更改它。

答案 1 :(得分:0)

您说bnil。这不会更改B.a,因为a是静态成员。在您的示例中,a未被取消初始化。如果您希望调用deinit,则必须为B.a分配一个新对象。但是,B.a是常数(let)。您可以将其更改为var,否则此特定对象将永远不会被取消初始化。

class B {
    static var a = A()
    \\ ...
}

B.a = A() //deinit of the old `B.a` is called

答案 2 :(得分:0)

在这种情况下,它不会因为B有强烈的A引用,但你可以在你的B类上做出类似static weak var a = A()的内容。当B = nil时,它将调用A的deinit,然后调用B。

答案 3 :(得分:0)

首先,当您将静态属性和方法定义到类(或结构)中时,这些变量保存在永久生成区域中。它将在所有实例(或值)之间共享。

这将通过两种方式发布:

  

1:当类被释放但是不可能看到因为   类正在堆上的特殊区域:永久生成   当应用程序终止时,类将被释放

     

2:你可以像这样强行分配nil

class A {
    init() {
        print("A init")
    }

    deinit {
        print("A deinit")
    }
}

class B {
    static var a:A? = A()

    deinit {
        print("B deinit")

    }

    init() {
        print("B init")
    }
    static func call(){
        a = nil
    }
}

var b: B? = B()
B.a
B.call() //forcely call 
b = nil

<强>输出

B init
A init
B deinit
A deinit