After implementing iOS for a while, if you start implementing Android after a long time, For some reason, I was a little annoyed that the Listener instance was released at a strange timing.
Perhaps everyone has written once, Delegate on iOS, Listener on Android ↓ I implemented it like this. I don't care about the method name or the wrong style this time.
iOS
import UIKit
// UI
class ViewController: UIViewController, ModelDelegate {
let model = Model()
override func viewDidLoad() {
super.viewDidLoad()
model.delegate = self
}
func notify(model: Model) {
}
}
//Model and protocol for notifications
protocol ModelDelegate: class {
func notify(model: Model)
}
class Model {
weak var delegate: ModelDelegate?
func doSomething() {
//Do something
delegate?.notify(model: self)
}
}
Android
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.lang.ref.WeakReference;
// UI
public class MainFragment extends Fragment {
private Model model;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
this.model = new Model();
model.setListener(new ModelListener() {
@Override
public void notify(Model model) {
}
});
return super.onCreateView(inflater, container, savedInstanceState);
}
}
//Model and interface for notifications
interface ModelListener {
void notify(Model model);
}
class Model {
private WeakReference<ModelListener> mListener;
void setListener(ModelListener listener) {
mListener = new WeakReference<>(listener);
}
void doSomething() {
//Do something
//Actually check null
mListener.get().notify(this);
}
}
So, this works fine on iOS.
It seems to work fine on Android, but at one point mListener.get ()
suddenly returns null.
It was said that if implemented with an anonymous class, there is no instance that strongly references Listener, so it will be the target of GC.
mListener.get ()
will return null when the GC runs.
It was okay because it was strongly referenced when implemented in a normal class, not an anonymous class.
(Then shouldn't it be a Weak Reference? But if you make a strong reference, it will circulate when you implement it in a normal class that is not an anonymous class. Eh, is java a fucking language that forces you to implement an interface?)
I thought, but of course that wasn't the case, and I was the one who was shit.
As you may have noticed, java has a GC, so there is no problem even if it circulates. So I changed it to a normal reference instead of a Weak Reference.
People who have only done iOS should be careful when writing a language with GC.
It was a good experience to realize that anonymous classes are a possible concept because of GC.
Recommended Posts