简体   繁体   English

Deinit被称为但对象仍在记忆中

[英]Deinit Called But Object Still in Memory

I'm seeing strange behavior with the allocations instrument in Xcode 8 and Swift 2.3. 我在Xcode 8和Swift 2.3中看到了分配工具的奇怪行为。 I have an object (A) on which deinit is being called, all but one of the objects that A references are being deallocated (the one that isn't is a separate memory issue as far as I can tell), but the object continues to be listed as "live" and persistent in the allocations instrument. 我有一个对象(A),在其上调用deinit ,除了其中一个对象,A引用被释放(据我所知,不是一个单独的内存问题),但对象继续被列为“实时”并在分配工具中持久存在。 Additionally, when I try to debug it's retains, all I see is: 另外,当我尝试调试它的保留时,我看到的只有:

在此输入图像描述

Note that I've confirmed deinit is being executed by: 请注意,我已确认deinit正在执行:

  • Adding a print line to the deinit method 在deinit方法中添加打印行
  • Adding a breakpoint to the deinit method 在deinit方法中添加断点
  • Verifying that other objects that A references are de-allocated, and they receive a release (-1) ref count that claims to happen inside of the A.__deallocating_deinit method 验证A引用的其他对象是否已取消分配,并且它们收到声明发生在A.__deallocating_deinit方法内的release(-1)引用计数

However, for some unknown reason it appears to stick around. 然而,由于一些未知的原因,它似乎坚持下去。

After a few more hours of searching I finally managed to (mostly) figure it out. 经过几个小时的搜索,我终于设法(大部分)弄明白了。

In this case, I have class A which has 6 properties, one of which is an instance of class B. Class A registers block callbacks with class B. Class B receives events from outside of the main run loop, on a separate NSThread that wasn't properly wrapped in an @autoreleasepool. 在这种情况下,我有一个类A,它有6个属性,其中一个是类B的实例。类A用类B注册块回调。类B接收来自主运行循环外部的事件,在一个单独的NSThread上没有正确包装在@autoreleasepool中。 As a result, Class B was being retained longer than intended, which resulted in its blocks with callbacks to A being retained longer than intended. 结果,B类保留的时间比预期的长,这导致其对A的回调被保留的时间长于预期。

The reason I say "mostly" figured it out is because class A registered all those blocks with [unowned self] . 我之所以说“大部分时间”都认为这是因为A级用[unowned self]注册了所有这些块。 For a still unknown reason, that seemed to be enough to allow deinit to be executed, but not enough to actually free the object. 由于一个仍然未知的原因,这似乎足以让deinit被执行,但还不足以实际释放该对象。 Wrapping the other thread in @autoreleasepool allowed the app to release B, which was then enough to release A. 在@autoreleasepool中包装其他线程允许应用程序释放B,这足以释放A.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM