My name is Anton Malygin, I have been working as an iOS developer for about 10 years. I’ll tell you about a fairly common problem.
When developing for iOS, many developers often encounter a retain cycle when at least 2 objects hold strict references to each other. The simplest case is when the developer simply forgot to make weak at delegate (yes, this happens) or called self in the escaping closure of a child object.
In a real large project, it is very difficult to find who holds a strong link to each other, and it may not be 2 objects.
Debug Memory Graph
There is a wonderful tool in Xcode — Debug Memory Graph.
In the debag mode, you need to click on the corresponding button on the debag panel.
After that, a list of all objects will appear on the left, which can be filtered to find the necessary one.
This will allow you to see the graph of objects and links between them.
Debug Memory Graph, like any tool, has errors. For example, it seems that if there is a retain cycle, then you can see something like this on the graph:
But in a real project, I have never seen such a graph when it was necessary to find a retain cycle. Apparently, it depends on the number of objects, the size of the call stack, etc. But, in fact, in a large project, and even in addition with RxSwift, this tool will not display the real picture, but will show something similar to the example above with a cell, only with a large number of links.
So, I’ll tell you a couple of useful nuances that have always helped me make this tool, even if it doesn’t work perfectly, but help me find a retain cycle.
First, one cannot hope that all links are shown on the graph!
In fact, it displays only a part of the links if there are many of them. And here we need to reduce the number of links in the old—fashioned way – to comment out the code, where, for example, there are any links, weak or strong, to the object we need. So, you may have to do several iterations, and each time links that were not displayed earlier will appear in the graph. Until we find the object that holds a strong reference.
The second point is to enable Malloc Stack Logging, I think the name speaks for itself.
We go into editing the project schema:
After that, when debagging, the call stack will be displayed on the right, in which memory for objects was allocated. This will help you look for places where strict object references could be created.
The method described above has repeatedly helped me find retain cycle in very large projects with a lot of reactivity, written by large teams.