Swift 在特定情况下不调用Denit
我有以下测试用例:我希望在程序终止时调用Swift 在特定情况下不调用Denit,swift,automatic-ref-counting,Swift,Automatic Ref Counting,我有以下测试用例:我希望在程序终止时调用deinit,但它从来都不是。我对斯威夫特还不熟悉,但我不认为这是意料之中的行为。(这不是在操场上) 输出为: Starting app init Ending App Program ended with exit code: 0 如果我把代码放在一个函数中,然后调用这个函数,我会得到预期的结果 Starting app init Ending App deinit Program ended with exit code: 0 程序终止时不应该调用
deinit
,但它从来都不是。我对斯威夫特还不熟悉,但我不认为这是意料之中的行为。(这不是在操场上)
输出为:
Starting app
init
Ending App
Program ended with exit code: 0
如果我把代码放在一个函数中,然后调用这个函数,我会得到预期的结果
Starting app
init
Ending App
deinit
Program ended with exit code: 0
程序终止时不应该调用对象的deinit吗?是一个类似的问题
在苹果公司,没有明确的解释如何使用deinit
。它只是在类释放时通过ARC调用。我认为当应用程序终止时,与类的常规运行时终止相比,有不同的终止机制。或者主窗口可以保留您的类?无论如何,为了在应用程序终止时执行代码,您应该使用应用程序委托(比如applicationWillTerminate
)
我希望在程序终止时调用Denit
你不应该期望那样。程序终止时存在的对象通常不会解除分配。内存清理留给操作系统(释放程序的所有内存)。这是Cocoa中一个长期存在的优化,用于加速程序终止
deinit
仅用于释放资源(例如释放不在ARC下的内存)。在Objc或SWIFT中没有等价的C++析构函数。(C++和Objective-C++对象在程序终止期间被销毁,因为这是规范要求的。)
如果我把代码放在一个函数中,然后调用我得到的函数
预期结果
Starting app
init
Ending App
deinit
Program ended with exit code: 0
是的,这是因为test
变量的寿命是由方法的范围定义的。当方法的作用域结束时(即,方法从堆栈中删除),所有局部变量的生命都将结束,除非有其他对这些变量的强引用
程序终止时不应该调用对象的deinit吗
在iOS中,无法像Android那样通过编程方式优雅地关闭应用程序。关闭应用程序的可能方式有:
从最近的应用列表中向上滑动(终止)
或故意撞车。
或者由于内存不足而让操作系统杀死你的应用。
当应用程序终止时,操作系统将清除所有应用程序的内存,因此不会调用deinit
,我们也不能期望这样。你可以注意到终止这个词,它解释了程序没有以正确的方式结束这一事实,因此我们不能期望操作系统完成最后的荣誉。正如它在顶层定义的那样,测试在技术上是一个全局变量,因此它实际上永远不会超出范围。如果将“主代码”放在中,请执行{…}
block,然后将调用deinit。@这毫无意义,它在程序终止时超出范围!(或者至少在逻辑上应该)。这很容易解决,但实际上毫无意义。@GregorBrandt你可以这么说,但反初始化程序在程序终止后不能运行:)尽管如此,顶级main.swift作用域已经相当特殊(全局变量没有惰性初始化器,你可以抛出未捕获的错误,等等),因此,在程序终止之前运行DeInitializers可能是合理的;请随意。