取消分配ViewController

时间:2017-06-28 02:12:00

标签: ios swift

我对iOS的内存泄漏和性能问题感到非常兴奋。目前我已经了解到通过保留周期避免泄漏。我在下面有一个片段,其中包含两个viewcontrollers,我正在通过委托传递数据。但是当我将委托var均衡为nil时,没有调用viewcontroller的deinit。

import UIKit

class ViewController: UIViewController, Navigator {


func passData(data: String) {
    print("Passed data: " + data)
}


override func viewDidLoad() {
    super.viewDidLoad()
}

deinit {
    print("deinited: " + self.description)
}

@IBAction func goSecond(_ sender: UIButton) {
    let secondVC = self.storyboard?.instantiateViewController(withIdentifier: "secondVC") as! SecondVC
    secondVC.delegate = self
    self.present(secondVC, animated: false, completion: nil)

}


}

// second vc

import UIKit



protocol Navigator: class{
func passData(data:String)
}

class SecondVC: UIViewController {
weak var delegate:Navigator?
override func viewDidLoad() {
    super.viewDidLoad()
}


@IBAction func GoFirst(_ sender: UIButton) {
   delegate?.passData(data: "I'm second VC and Passing")
   self.delegate = nil

}
}

1 个答案:

答案 0 :(得分:3)

您误解了deinit方法的工作。当视图控制器的实例没有任何引用时,应该调用deinit。因此,只是删除视图控制器属性的引用并不能完成整个工作。

你误以为self.delegate = nil中有SecondVC。这应该在您的第一个ViewController

中完成

为了理解一切,我做了一个示例项目,你可以在那里学习如何工作。主要代码在这里:

第一视图控制器

class FirstViewController: UIViewController, Navigator {

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    deinit {
        print("First view controller's deinit called")
    }

    func passData(data: String) {
        print("In First view controller: \(data)")
    }

    @IBAction func gotoSecond(_ sender: UIButton) {
        let viewcontroller = storyboard?.instantiateViewController(withIdentifier: "SecondViewController") as! SecondViewController
        viewcontroller.delegate = self
        show(viewcontroller, sender: self)
    }

}


第二视图控制器

protocol Navigator {
    func passData(data:String)
}

class SecondViewController: UIViewController {

    weak var delegate:Navigator?

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    deinit {
        print("Second view controller's deinit called")
    }

    @IBAction func closeButton(_ sender: UIButton) {
        delegate?.passData(data: "Delegation from second view controller")
        dismiss(animated: true, completion: nil)  //when this line executes, the instance of this class is de-referenced. This makes the call to deinit method of this class.
    }
}

因此,当第二个视图控制器发生dismiss时,第二个视图控制器的引用计数转到0,这样就可以调用第二个视图控制器的deinit方法。

  

但从技术上讲,您不会调用第一个视图的deinit   控制器,因为您实际上没有取消引用第一个视图   控制器。

您可以找到整个项目here