ARC(自动引用计数)在行动中

时间:2015-05-26 11:32:27

标签: swift automatic-ref-counting

我目前正在关注Apple Documentation。这是我的问题:

class Person {
    let name: String
    init(name: String) {
        self.name = name
        println("\(name) is being initialized")
    }
    deinit {
        println("\(name) is being deinitialized")
    }
}

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        var reference1: Person?
        var reference2: Person?
        var reference3: Person?
        reference1 = Person(name: "John Appleseed")
        // prints "John Appleseed is being initialized
        reference2 = reference1
        reference3 = reference1

        reference1 = nil
        reference2 = nil
    }
}

reference1等于nil后,ARC取消分配实例并打印"John Appleseed is being deinitialized"

reference3 = nil之后不应该解除分配吗?

2 个答案:

答案 0 :(得分:6)

这里的问题是范围问题。我们可以通过断点找到更多信息。

此处,我们在初始化reference1之前就已停止了。
所有变量都应该是nil

enter image description here

初始化reference1后?

enter image description here

好的,让我们在reference2reference3设置完毕后跳过:

enter image description here

所有三个变量都指向相同的内存位置,我们可以看到初始化程序只运行一次。这些都指向同一个位置。

让我们前进:

enter image description here

reference1现在指向None。它是nildeinit mmethod没有被调用并打印出它的消息。

让我们再向前迈进一步:

enter image description here

现在reference1reference2都是nil。我已添加的println语句被调用。但是deinit没有投放,reference3不是nil

下一步是完全退出方法。一旦我们退出该方法,变量就超出范围并调用deinit

enter image description here

答案 1 :(得分:1)

它正在解除分配,因为编译器能够识别出不再使用本地创建的对象。例如,在执行viewDidLoad方法Person之后,下面的代码将被解除分配,因为将来没有人使用person对象。

override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.\

        var reference1: Person?
        var reference2: Person?
        var reference3: Person?
        reference1 = Person(name: "John Appleseed")
        // prints "John Appleseed is being initialized
        reference2 = reference1
        reference3 = reference1

        reference1 = nil
        reference2 = nil

//        println(reference3?.name)
}

如果您想保留该对象,则需要将reference3创建为property,如下所示:

class ViewController: UIViewController {

    var reference3 : Person?

    override func viewDidLoad() {
        super.viewDidLoad()

        var reference1: Person?
        var reference2: Person?

        reference1 = Person(name: "John Appleseed")
        // prints "John Appleseed is being initialized
        reference2 = reference1
        reference3 = reference1

        reference1 = nil
        reference2 = nil

//        println(reference3?.name)
    }

    override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)
        println(reference3?.name)
    }

}