为啥我初始化 uiview 和 uiview 也被 swift 删除?

Posted

技术标签:

【中文标题】为啥我初始化 uiview 和 uiview 也被 swift 删除?【英文标题】: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.

【问题讨论】:

【参考方案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”来描述你将在同一个类或结构中初始化的属性。

【讨论】:

以上是关于为啥我初始化 uiview 和 uiview 也被 swift 删除?的主要内容,如果未能解决你的问题,请参考以下文章