ios - ViewController 的释放

标签 ios swift

我对 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/

相关文章:

ios/objective-c : Create Segue from Textview to View Controller in Storyboard

html - <input type ="search"> 在 iOS 下不再显示取消按钮 (x)

swift - 从哈希值计算中省略一个属性

swift - 在 SwiftUI 中处理派生状态

ios - 重写 Swift 中行插入的 withRowAnimation 样式

ios - 使用 GCD 并回调主线程时如何设置正确的对象拆卸?

swift - 有没有办法在 Swift 3 的计算属性中声明常量?

ios - 如何计算 UITableViewCell 中的 UILabel 正确行号?

swift - 覆盖 Swift 2 中的函数错误

html - 如何使 html 下拉列表在 ios web 应用程序中始终显示为滚动菜单?