Wenn Sie nach einer Weile der Implementierung von iOS nach einer langen Zeit mit der Implementierung von Android beginnen, Aus irgendeinem Grund war ich ein wenig verärgert darüber, dass die Listener-Instanz zu einem seltsamen Zeitpunkt veröffentlicht wurde.
Vielleicht hat jeder einmal geschrieben: Delegieren in iOS, Listener in Android ↓ Ich habe es so implementiert. Es ist mir egal, dass der Methodenname oder der Stil seltsam ist.
iOS
import UIKit
// UI
class ViewController: UIViewController, ModelDelegate {
let model = Model()
override func viewDidLoad() {
super.viewDidLoad()
model.delegate = self
}
func notify(model: Model) {
}
}
//Modell und Protokoll für Benachrichtigungen
protocol ModelDelegate: class {
func notify(model: Model)
}
class Model {
weak var delegate: ModelDelegate?
func doSomething() {
//Etwas tun
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);
}
}
//Modell und Schnittstelle zur Benachrichtigung
interface ModelListener {
void notify(Model model);
}
class Model {
private WeakReference<ModelListener> mListener;
void setListener(ModelListener listener) {
mListener = new WeakReference<>(listener);
}
void doSomething() {
//Etwas tun
//Eigentlich null prüfen
mListener.get().notify(this);
}
}
Das funktioniert also gut unter iOS.
Unter Android scheint es gut zu funktionieren, aber irgendwann gibt mListener.get ()
plötzlich null zurück.
Es wurde gesagt, dass es bei einer Implementierung mit einer anonymen Klasse keine Instanz geben würde, die stark auf Listener verweist, sodass sie der GC unterliegen würde.
MListener.get ()
gibt null zurück, wenn der GC ausgeführt wird.
Es war in Ordnung, weil bei der Implementierung in einer normalen Klasse, nicht in einer anonymen Klasse, stark darauf verwiesen wurde.
(Dann sollte es nicht eine schwache Referenz sein? Wenn Sie jedoch eine starke Referenz angeben, wird diese verbreitet, wenn Sie sie in einer normalen Klasse implementieren, die keine anonyme Klasse ist. Eh, ist Java eine verdammte Sprache, die dich zwingt, die Schnittstelle zu implementieren?)
Natürlich war das nicht der Fall und ich war derjenige, der fickte.
Wie Sie vielleicht bemerkt haben, hat Java einen GC, so dass es kein Problem gibt, selbst wenn es zirkuliert. Also habe ich es in eine normale Referenz anstelle von WeakReference geändert.
Leute, die nur iOS gemacht haben, sollten vorsichtig sein, wenn sie eine Sprache mit GC schreiben.
Es war eine gute Erfahrung zu erkennen, dass anonyme Klassen aufgrund von GC ein mögliches Konzept sind.
Recommended Posts