我对 iOS 的内存泄漏和性能问题感到非常兴奋。目前我已经了解到,通过保留循环来避免泄漏。我下面有一个片段,其中包含两个 View Controller ,我正在通过委托(delegate)传递数据。但是当我将 delegate 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)
}
}
//第二个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
}
}
最佳答案
您误解了 deinit
方法的工作。当 View Controller 的实例没有剩余引用时,应该调用 deinit。因此,仅仅删除 View Controller 属性的引用并不能完成全部工作。
并且您对在 SecondVC
中设置 self.delegate = nil
存在误解。这应该在您的第一个 ViewController
中完成。
为了理解一切,我做了一个示例项目,您可以在其中了解 deinits 的工作原理。主要代码在这里:
第一个 View Controller
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)
}
}
第二个 View Controller
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.
}
}
因此,当第二个 View Controller 发生 dismiss
时,第二个 View Controller 的引用计数将变为 0
,这将完成调用 deinit
第二个 View Controller 的方法。
But you technically don't call the
deinit
of the first view controller as you don't actually de-reference the first view controller.
您可以找到整个项目here .
关于ios - ViewController 的释放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44792583/