swift 在特定情况下未调用deinit

ddhy6vgd  于 2023-04-19  发布在  Swift
关注(0)|答案(4)|浏览(225)

我有以下测试用例:我希望deinit在程序终止时被调用,但它从来没有。我是Swift的新手,但不认为这是预期的行为。(这不是在操场上)

class Test
{
   init() {
      print( "init" )
   }

   deinit {
      print( "deinit" )
   }
}

print("Starting app")

var test = Test()

print( "Ending App" )

输出为:

Starting app
init
Ending App
Program ended with exit code: 0

如果我把代码放在一个函数中,然后调用这个函数,我会得到预期的结果

Starting app
init
Ending App
deinit
Program ended with exit code: 0

在程序终止时不应该调用对象的deinit吗?

guicsvcw

guicsvcw1#

我期望在程序终止时调用deinit
你不应该期望这样。程序终止时存在的对象通常不会被释放。内存清理留给操作系统(释放程序的所有内存)。这是可可中长期存在的优化,以加快程序终止。
deinit仅用于释放资源(例如释放不在ARC下的内存)。在ObjC或Swift中没有C析构函数的等价物。(C和Objective-C++对象在程序终止时被销毁,因为这是规范要求的。)

arknldoa

arknldoa2#

如果我把代码放在一个函数中,然后调用这个函数,我会得到预期的结果
是的,这是可行的,因为test变量的生命是由方法的作用域定义的。当方法的作用域结束时(* 即方法从Stack* 中删除),所有局部变量的生命都将结束,除非有其他对这些变量的强引用。
在程序终止时不应该调用对象的deinit吗
在iOS中没有办法像Android那样通过编程方式优雅地关闭应用程序。可以关闭应用程序的可能方式有,
1.通过从最近的应用列表中向上滑动(终止)
1.或者故意撞车
1.或者由于内存不足,让操作系统终止您的应用。
当应用程序终止时,所有的内存都将被操作系统清除,所以deinit不会被调用,我们也不能期望这样。你可以注意到termination这个词,它解释了程序没有以正确的方式结束的事实,所以我们不能期望操作系统做最后的荣誉。

yqlxgs2m

yqlxgs2m3#

There是一个类似的问题。
在Apple中,没有明确的解释deinit是如何工作的。只是当类被释放时,它由ARC调用。我认为当应用程序终止时,与常规运行时类的deiniting相比,有不同的deiniting机制。或者主窗口保留了你的类?无论如何,为了在应用程序终止时执行代码,你应该使用Application delegate(如applicationWillTerminate)。

nue99wik

nue99wik4#

Deinit函数只在测试对象被释放时工作,在第一种情况下应该这样做以确保测试对象被释放:

class Test {

init() {
    print( "init" )
}

deinit {
    print( "deinit" )
}
}

print("Starting app")
var test: Test? = Test()
test = nil
print("Ending App")

然后deinit将如您所期望的那样被调用。
在第二种情况下,当你的代码推入一个函数时,object在函数作用域结束时将被dealloc,所以在这种情况下将调用deinit
欲了解更多信息,应该访问那里:https://docs.swift.org/swift-book/documentation/the-swift-programming-language/deinitialization

相关问题