[JAVA] Eine Geschichte, dass eine Person, die ein solides iOS gemacht hat, möglicherweise von der Implementierung von Listener abhängig ist, wenn sie zu Android wechselt

zunaechst

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.

Was ich getan habe

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.

Ursache

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.

Gedanken

(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.

Nach alldem

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.

Am Ende

Es war eine gute Erfahrung zu erkennen, dass anonyme Klassen aufgrund von GC ein mögliches Konzept sind.

Recommended Posts

Eine Geschichte, dass eine Person, die ein solides iOS gemacht hat, möglicherweise von der Implementierung von Listener abhängig ist, wenn sie zu Android wechselt
Die Geschichte der Einführung von Gradle als Nachrüstung eines bestehenden Systems, das keine Pakete verwaltet
Ein Memo, das nüchtern von der Anfrage nach mehrteiligen / Formulardaten abhängig war
Eine Geschichte, der ich beim Testen der API mit MockMVC verfallen war
Eine Geschichte, die die Implementierung der SendGrid-Java-Bibliothek bestätigt, wenn die E-Mail-Zustellung fehlschlägt
Eine Geschichte, die süchtig nach EntityNotFoundException von getOne of JpaRepository ist
Beachten Sie, dass ich von den Einstellungen des Android-Projekts von IntelliJ IDEA abhängig war
Eine Geschichte, nach der ich süchtig war, als ich einen Schlüssel bekam, der automatisch auf MyBatis ausprobiert wurde
Konvertieren Sie ein potenziell null-Array in einen Stream
Die Geschichte, nach der ich beim Einrichten von STS süchtig war
Eine Sammlung von Mustern, die Sie kennen möchten, um den Code nicht zu komplizieren
Versuchen wir die Implementierung, um den Bereich des Dreiecks zu finden, den wir im Training für Neuankömmlinge durchgeführt haben
Eine Geschichte, die mich bedauerte, als während der Entwicklung der Spring Boot-App eine "NotReadablePropertyException" auftrat.
[Rails] Eine Geschichte, die weiterhin fälschlicherweise den Grund überprüfte, warum die Aktualisierungsaktion nicht bestanden wurde (Aktualisierung)
Eine Geschichte, die mithilfe von Polymorphismus sauber implementiert werden kann, wenn Sie zwei Datentypen in einer Tabelle ausdrücken möchten