我有以下测试用例:我希望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吗?
4条答案
按热度按时间guicsvcw1#
我期望在程序终止时调用deinit
你不应该期望这样。程序终止时存在的对象通常不会被释放。内存清理留给操作系统(释放程序的所有内存)。这是可可中长期存在的优化,以加快程序终止。
deinit
仅用于释放资源(例如释放不在ARC下的内存)。在ObjC或Swift中没有C析构函数的等价物。(C和Objective-C++对象在程序终止时被销毁,因为这是规范要求的。)arknldoa2#
如果我把代码放在一个函数中,然后调用这个函数,我会得到预期的结果
是的,这是可行的,因为
test
变量的生命是由方法的作用域定义的。当方法的作用域结束时(* 即方法从Stack
* 中删除),所有局部变量的生命都将结束,除非有其他对这些变量的强引用。在程序终止时不应该调用对象的deinit吗
在iOS中没有办法像Android那样通过编程方式优雅地关闭应用程序。可以关闭应用程序的可能方式有,
1.通过从最近的应用列表中向上滑动(终止)
1.或者故意撞车
1.或者由于内存不足,让操作系统终止您的应用。
当应用程序终止时,所有的内存都将被操作系统清除,所以
deinit
不会被调用,我们也不能期望这样。你可以注意到termination这个词,它解释了程序没有以正确的方式结束的事实,所以我们不能期望操作系统做最后的荣誉。yqlxgs2m3#
There是一个类似的问题。
在Apple中,没有明确的解释
deinit
是如何工作的。只是当类被释放时,它由ARC调用。我认为当应用程序终止时,与常规运行时类的deiniting相比,有不同的deiniting机制。或者主窗口保留了你的类?无论如何,为了在应用程序终止时执行代码,你应该使用Application delegate(如applicationWillTerminate
)。nue99wik4#
Deinit函数只在测试对象被释放时工作,在第一种情况下应该这样做以确保测试对象被释放:
然后deinit将如您所期望的那样被调用。
在第二种情况下,当你的代码推入一个函数时,object在函数作用域结束时将被dealloc,所以在这种情况下将调用deinit
欲了解更多信息,应该访问那里:https://docs.swift.org/swift-book/documentation/the-swift-programming-language/deinitialization