【问题标题】:Why I init the uiview and the uiview also deinit by swift?为什么我初始化 uiview 和 uiview 也被 swift 删除?
【发布时间】:2017-10-13 08:13:11
【问题描述】:

我想管理内存,所以我想在离开 ViewController 时取消 UIview。
我尝试使用关键字“weak”,但由于我的聊天键盘为 nil,所以我崩溃了。
我不知道为什么让它崩溃。
谢谢。

class ChatKeyboard: UIView {

var buttonMic:UIButton = { ()->UIButton in
    let ui:UIButton = GeneratorButton()
    return ui
}()

override init(frame: CGRect) {
    super.init(frame: frame)
    print("===) ChatKeyboard init.")
    translatesAutoresizingMaskIntoConstraints = false
    loadContent()
    loadConstrain()
}

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
}

deinit {
    print("===) ChatKeyboard deinit.")
}

func loadContent() {

backgroundColor = UIColor.white
addSubview(buttonMic)
}

func loadConstrain() {

buttonMic.snp.makeConstraints { (make) -> Void in
           make.left.equalTo(micLeftPadding)
           make.top.equalTo(micTopPadding)
           make.width.equalTo(UIScreen.main.bounds.width*0.0581)
           make.height.equalTo(UIScreen.main.bounds.height*0.045)
}
}
}


class ChatroomViewController: UIViewController{

weak var chatKeyboard:ChatKeyboard?

override func viewDidLoad() {
    super.viewDidLoad()

    chatKeyboard = ChatKeyboard(frame: CGRect(x: 0, y: 0, width: 300, height: 44))
}
}

我在“chatKeyboard = ChatKeyboard(frame: CGRect(x: 0, y: 0, width: 300, height: 44))”处设置断点,然后我的日志打印:

===) ChatKeyboard init.
===) ChatKeyboard deinit.

【问题讨论】:

    标签: ios swift uiview initialization


    【解决方案1】:

    只要没有强引用,weak 变量就会被销毁。

    如果您正在创建视图并将其直接分配给weak 变量,它将立即被销毁。弱 IBOutlets 之所以起作用,是因为它们在分配给变量之前被添加到超级视图(创建强引用)。您可以在分配给您的属性之前使用局部变量来实现这一点:

    let keyboard = ChatKeyboard(...)
    view.addSubview(keyboard)
    chatKeyboard = keyboard
    

    然而,你的视图控制器对它关心的视图有强引用并没有什么坏处,只要这些视图也没有对视图控制器的强引用。当视图控制器被销毁时,它们将被销毁。

    【讨论】:

      【解决方案2】:

      原因是您已将 chatKeyBoard 声明为

      weak var chatKeyboard:ChatKeyboard?
      

      这意味着您的 viewController 不会对您加载的视图进行任何强引用。因此视图的引用计数不会改变。

      在你看来DidLoad

      override func viewDidLoad() {
          super.viewDidLoad()
      
          chatKeyboard = ChatKeyboard(frame: CGRect(x: 0, y: 0, width: 300, height: 44))
      }
      

      您实例化了视图,但是因为一旦控件超出 viewDidLoad 的范围,视图就被弱保持,ARC 释放了视图。

      如果您希望即使在调用 viewDidLoad 之后也可以访问您的视图,请声明一个强引用

      var chatKeyboard:ChatKeyboard?
      

      希望对你有帮助

      【讨论】:

        【解决方案3】:

        在一个类或结构中,不要使用关键字“weak”来描述你将在同一个类或结构中初始化的属性。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-10-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-06-26
          • 1970-01-01
          • 2012-04-12
          相关资源
          最近更新 更多