Après un certain temps d'implémentation d'iOS, si vous commencez à implémenter Android après une longue période, Pour une raison quelconque, j'étais un peu ennuyé que l'instance Listener soit sortie à un moment étrange.
Peut-être que tout le monde a écrit une fois, Delegate sous iOS, Listener sous Android ↓ Je l'ai implémenté comme ça. Je me fiche du fait que le nom de la méthode ou le style soit étrange.
iOS
import UIKit
// UI
class ViewController: UIViewController, ModelDelegate {
let model = Model()
override func viewDidLoad() {
super.viewDidLoad()
model.delegate = self
}
func notify(model: Model) {
}
}
//Modèle et protocole pour les notifications
protocol ModelDelegate: class {
func notify(model: Model)
}
class Model {
weak var delegate: ModelDelegate?
func doSomething() {
//Faire quelque chose
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);
}
}
//Modèle et interface pour la notification
interface ModelListener {
void notify(Model model);
}
class Model {
private WeakReference<ModelListener> mListener;
void setListener(ModelListener listener) {
mListener = new WeakReference<>(listener);
}
void doSomething() {
//Faire quelque chose
//Vérifier en fait null
mListener.get().notify(this);
}
}
Donc, cela fonctionne très bien sur iOS.
Cela semble fonctionner correctement sur Android, mais à un moment donné, mListener.get ()
retourne soudainement null.
Il a été dit que si elle était implémentée avec une classe anonyme, aucune instance ne ferait fortement référence à Listener, elle serait donc soumise à GC.
MListener.get ()
retournera null lors de l'exécution du GC.
C'était correct car il était fortement référencé lorsqu'il était implémenté dans une classe normale, pas dans une classe anonyme.
(Alors ne devrait-il pas être une référence faible? Mais si vous faites une référence forte, elle circulera lorsque vous l'implémenterez dans une classe normale qui n'est pas une classe anonyme. Eh, est-ce que java est un putain de langage qui vous oblige à implémenter une interface?)
Bien sûr, ce n'était pas le cas, et c'était moi qui baisais.
Comme vous l'avez peut-être remarqué, java possède un GC, il n'y a donc pas de problème même s'il circule. Je l'ai donc changé pour une référence normale au lieu de WeakReference.
Les personnes qui n'ont fait qu'iOS doivent être prudentes lors de l'écriture d'un langage avec GC.
Ce fut une bonne expérience de réaliser que les classes anonymes sont un concept possible grâce à GC.
Recommended Posts