Reference leaking with setDelegate / setDataSource etc

I found that there is no document about how to correctly using setXXXX() and setXXXX_unsafe().

The document only says about don’t use setXXXX_unsafe() if the object is not retained in your Java code (for example, an instance created in a method without a global reference).

The opposite situation which I found in my project is not mentioned in the MOE document, and I think is pretty common in practice: your class extends an ViewController and also implement XXXXDelegate.

Think about it, if you use this.setDelegate(this), the MOE natj will add the retain count by calling org.moe.natj.objc.ObjCRuntime.associateObjCObject(), which, causes an cyclic reference: this view controller keeps an additional reference of itself, hens it will never released.

In this case, we should use setXXXX_unsafe() instead, since we don’t need MOE to add an additional reference to this delegate / data source: you are setting yourself as a delegate / data source.

I have created a sample project to show you the difference between setDelegate() and setDelegate_unsafe() in this case, you could download it here:

  1. Build and install, run the app.
  2. Tap on Navigate button, then go back. Repeat several times.
  3. Tap on Navigate Unsafe button, then go back. Repeat several times.
  4. Tap on Force GC button several times to release memory.
  5. Tap on Dump Heap.
  6. Open iTunes, go to app->file sharing, find this app, save the dump file to your computer.
  7. Open this hprof file with android studio / IDEA with android plugin installed.
  8. See the difference between the reference count of BrowserViewController and BrowserUnsafeViewController.

2 Likes

Well I’m not 100% sure about my analysis, but the result is pretty clear. :slight_smile:
Not familiar with the memory management in iOS. Hopefully I got it right ;).