iosswiftstrong-references

Finding cause of strong reference cycle


I have some trouble finding the cause of a View Controller not being released. It only appears at the top of the hierarchy as it is a sub page with the only purpose being to chat(a minor feature) with other users of the app.

I have already tried using instruments and the only information I can find is that the cause of retaining is one count from UIKit - UIClassSwapper which does not make much sense to me.

enter image description here

I use the following within the controller:

  1. Realm - storing of chat history locally
  2. Socket IO - real time sending and receiving of messages
  3. UITableView+delegate - displaying messages
  4. UITextView+delegate - typing message
  5. NotificationCenter - for behavior when keyboard appears/disappear and app entering background/foreground

No custom delegate are used and explicit strong reference to self is used within this controller. The chat bubbles have custom drawing codes which add layers but does not require a reference from any other views.

What could have caused the View Controller to be retained?

This is important as each view controller retained will cause the socket to respond to events sent by the server. Making each user count as multiple after some time.

Please do mention if any particular part of the codes has higher chance of causing this problem and I'll add it to my question. The entire view controller is more than 400 lines of codes and is not practical to have it fully in my question.

Edit

I took inokey's suggestion and break down each part to debug, the cause of the retain cycle is actually Socket IO. I also reread the documentation of Socket IO and found out that there is a removeAllHandlers() method that will remove all references that may result in strong reference cycles.

End up it is my mistake for not reading documentation carefully -.-


Solution

  • When using a lot of external stuff like Socket Client or Realm Client there's a huge opportunity for having some strong references by these guys. I suppose if the question is what causes retain cycle you can try few approaches.

    First. Try to remove one by one anything that shouldn't actually belong to the VC in the original MVC pattern. That's is obviously socket and realm. Ideally they should be encapsulated in some sort of services and used by a a service. Not by VC directly.

    Second. Check if these objects are being deinitialized when you suggest they should. You can do that by adding deinit() method to them.

    Third. Which comes from both of above is: Try answer the question how do you even initialize those things?

    I'm sorry I can't be more specific, but I hope this will lead you to right thoughts.