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