【问题标题】:ios: why it call deinit immediatelyios:为什么它立即调用 deinit
【发布时间】:2023-03-20 16:30:01
【问题描述】:

今天遇到一个问题,vc从来不调用deinit,所以我加了一个weak

func showAddCityViewController() {
        weak var vc:SWAddCityViewController!
        vc =  SWAddCityViewController()
        vc.delegate = self
        let nav = UINavigationController(rootViewController: vc)
        dispatch_async(dispatch_get_main_queue(), {
            self.presentVC(nav)
        })
    }

我运行这个函数然后得到一个

致命错误:在展开可选值时意外发现 nil

vc 刚到 nil ,但我不知道为什么,我应该怎么做才能让这段代码快乐?

【问题讨论】:

  • 如果你将变量设为weak,那么该对象将不会被保留。你为什么这样做?普通的 let vc = SWAddCityViewController() 有什么问题?
  • @Thilo 对不起,我是新手,vc 只是不要调用 deinit

标签: ios swift


【解决方案1】:

这是你写的:

    weak var vc:SWAddCityViewController!
    vc =  SWAddCityViewController()

vc 变量是一个“隐式展开的 Optional”,这意味着它可以指向现有的(未释放的)对象,也可以为 nil。

您创建一个新的SWAddCityViewController 对象并将其分配给vc。赋值语句完成后,对新对象(在vc 中)只有一个弱引用,并且没有对它的强引用。对象在没有强引用时立即被释放,因此在赋值语句完成后立即释放。

由于vc 是对该对象的弱引用,因此解除分配对象的一部分会将vc 设置为nil。当您尝试在下一行设置vc.delegate 时,Swift 会生成代码以自动解开vc(因为您使用! 声明了它)。由于vc 为 nil,因此您会遇到致命错误。您不能解开设置为 nil 的可选项,因为它没有包装任何东西。

我看不出有任何理由在该函数中声明 vc 弱。只需去掉 weak 属性即可。

您的另一个抱怨是(使用weak)该对象稍后不会被释放。你有一个“保留周期”。您是否使用weak 声明了SWAddCityViewControllerdelegate 属性?你通常要声明delegate 属性weak

如果这不能解决问题,您需要寻找其他有涉及该对象的保留循环的地方。

【讨论】:

  • 谢谢,问题是vc在关闭的时候没有调用deinit,我不知道为什么,SWAddCityViewController中根本没有关闭
  • 我认为这可能是一个保留周期
  • 谢谢你这么长的回答,是的,它应该是 SWAddCityViewController 中的一个保留周期,但我找不到它,我使用弱委托,但它不起作用
  • ohha,解决了,是delegate不爽,我在SWAddCityViewController中使用了一个自定义的tableviewcell,并让SWAddCityViewController成为了自定义tableviewcell的delegate,不弱,现在SWAddCityViewController调用了deinit。真的谢谢。
猜你喜欢
  • 2021-05-16
  • 1970-01-01
  • 1970-01-01
  • 2019-02-06
  • 1970-01-01
  • 2021-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多