UIViewController with CFNotificationCenter strong reference won't release
Asked Answered
D

2

8

I have a view controller that is never released once its parent view controller is removed from the view hierarchy and released. Every instance of it within the memory graph looks the same in that it has a single reference to CFNotificationCenter. It appears that other, not relevant, view controllers of a different class all have this same reference but still get released. The view controller in question also doesn't have any NotificationCenter observers so this makes no sense to me.

I have attached an image of the memory graph with the true name of the view controller redacted. I am also sure that this is the full graph of the view controller, I have not have selected to inspect a single reference.

The confusing memory graph

What is happening here? Why won't it be released?

Drewdrewett answered 10/12, 2020 at 19:2 Comment(0)
P
7

You can see exactly what code is referencing your View Controller:

First, turn on Malloc Stack Logging for your scheme (open the scheme editor with Cmd-Shift-,) Screenshot of the Xcode Scheme editor

Then, click the "malloc" block that is pointing to your View Controller, and mouseover to the right of Backtrace to find the "Expand" button to see the full stack trace: Screenshot of the Xcode memory graph debugger

However, the most likely culprit is not actually the notification retaining your View Controller, as the reference is not strong (otherwise it would be a bold arrow).

The Xcode memory graph debugger doesn't show you when an object is retaining itself. In my case it was a simple case of retaining self in a closure in my viewDidLoad.

Phillane answered 1/2, 2021 at 0:50 Comment(2)
Might have better luck with Instruments.Lewandowski
Inspecting the malloc backtrace revealed the issue: a strong reference to self in an escaping closure. The CFNotificationCenter was only a red herring, hence why it was in the backtrace of every other element.Drewdrewett
K
0

I have this issue in my project too. And I found that if I assign the object to nil while calling CFNotificationCenterAddObserver and CFNotificationCenterRemoveObserver, I still can receive the notification - and without the retain issue when deinitializing the object, which I added as the listener previously.

Kristoforo answered 30/8, 2021 at 3:23 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.