Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deinit Called But Object Still in Memory

Tags:

I'm seeing strange behavior with the allocations instrument in Xcode 8 and 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. Additionally, when I try to debug it's retains, all I see is:

enter image description here

Note that I've confirmed deinit is being executed by:

  • Adding a print line to the deinit method
  • Adding a breakpoint to the deinit method
  • 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

However, for some unknown reason it appears to stick around.

like image 999
Colin M Avatar asked Sep 19 '16 03:09

Colin M


1 Answers

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. 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.

The reason I say "mostly" figured it out is because class A registered all those blocks with [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. Wrapping the other thread in @autoreleasepool allowed the app to release B, which was then enough to release A.

like image 160
Colin M Avatar answered Sep 26 '22 16:09

Colin M