为什么我的实例没有被解除分配?

时间:2017-04-13 19:35:34

标签: swift memory-management

我有一个Person类,如下所示:

D-E-F-G-H

我在下面的viewController中创建了一个A-B-C的实例:

-m 1

如果我有10 PRINT "START " TI 20 T0=T1 30 IF TI-T0>=60 THEN PRINT TI;TI-T0 : GOTO 20 40 GOTO 30 ,那么我的class Person{ var name: String? init(name: String){ self.name = name } func doWithDelay(){ let when = DispatchTime.now() + 2 DispatchQueue.main.asyncAfter(deadline: when) { [weak self] in self?.name = "delayed" print(self?.name ) } } deinit { print("Person class is deinited \(self)") } } 实例取消分配,但是如果我注释掉行AAA或只是将其替换为Person那么我的实例class ViewController: UIViewController { var p1 :Person? = Person(name: "MMM") override func viewDidLoad() { super.viewDidLoad() var persons : [Person] = [] p1!.doWithDelay() persons.append(p1!) var p3 = Person(name: "OOO") // AAA persons.removeAll() } } 实例赢得根本无法取消分配。

为什么?!

1 个答案:

答案 0 :(得分:2)

问题在于你无法告诉另一个人。像这样重写你的Person类:

class Person: NSObject{
    var name: String?

    init(name: String){
        self.name = name
        super.init()
        NSLog("%@", "Person class is inited \(self)")
    }
    func doWithDelay(){
        let when = DispatchTime.now() + 2
        DispatchQueue.main.asyncAfter(deadline: when) { [weak self] in
            self?.name = "delayed"

            print(self?.name )
        }
    }
    deinit {
        NSLog("%@", "Person class is deinited \(self)")
    }
}

这里的区别是(1)我们在init以及dealloc期间记录,而(2)我们从NSObject派生,因为它为self提供了唯一的标识符,即它的内存地址。然后我们得到:

Person class is inited
<MyApp.Person: 0x618000047470> 
Person class is inited 
<MyApp.Person: 0x61000004b040> 
Person class is deinited 
<MyApp.Person: 0x61000004b040>

这正是我们期望看到的:实例属性Person仍然存在,但是局部变量Property被创建并立即再次销毁。局部变量是自动:一旦我们到达其范围的末尾(包含花括号),它们就会被释放,因此局部变量引用的对象会消失,除非您安排了更长的时间 - 保留它的生命参考。