Was verursacht dieses Initialisierungsproblem bei UIBarButtonItem?

8

Ich versuche, eine einfache Swift-Unterklasse von UIBarButtonItem zu erstellen:

%Vor%

aber wenn ich versuche, dies zu instanziieren:

%Vor%

Der Code wird korrekt kompiliert, scheitert jedoch zur Laufzeit mit:

%Vor%

Ich kann nicht verstehen, warum dies in diesem Fall passiert oder welches Prinzip dieses Problem im Allgemeinen verursacht. Der Initiator init(text) sollte direkt an init(customView) in der Oberklasse delegieren. Warum wird init() überhaupt aufgerufen? Es sollte nicht beteiligt sein.

Kann jemand erklären, was passiert? Ähnliche Probleme sind aufgetreten, wenn ich versucht habe, andere UIKit-Klassen zu unterklassen

    
Bill 24.11.2014, 22:47
quelle

2 Antworten

4

Das Problem ist, dass init(customView:) init() aufruft.

Und da Sie einen erforderlichen Initialisierer haben, erben Sie init() nicht mehr. Sie müssen es also implementieren, auch wenn Sie nur super.init() aufrufen.

Sie stehen dann vor dem (leichten) Ärger, alle Ihre Eigenschaften in init() sowie in init(text:) initialisieren zu müssen. In Ihrem speziellen Fall war dies jedoch in einem Initialisierer überhaupt nicht erforderlich. Ich schreibe deine Klasse so:

%Vor%

In Ihrem Kommentar fragen Sie:

  

Aber jetzt, wenn ich init () überschreibe, können Clients meiner Klasse eine ungültige Instanz von LabelBarButtonItem erstellen, indem sie einfach LabelBarButtonItem ()

aufrufen

Richtig. Deshalb habe ich die init() override als private markiert. Beachten Sie, dass dies nur funktioniert, wenn diese Klasse in einer Datei selbst deaktiviert ist.

Eine andere Möglichkeit besteht darin, alle Initialisierer (einschließlich init(coder:) ) als convenience zu markieren. Jetzt erben Sie init() und das ganze Problem verschwindet. Dies führt jedoch zu einer weiteren Reihe von Problemen und bleibt dem Leser als Übung überlassen.

Nur zur Klarstellung, ich betrachte diese ganze Situation als einen Fehler in Swift. Es verhält sich nicht so, IIRC, bis vor kurzem eine Revision (Xcode 6.1?). Sie werden durch die Tatsache eingeschränkt, dass super.init(customView:) Ihr init() aufruft. Du könntest argumentieren, dass das falsch ist; Sie haben einen guten Anwendungsfall für einen Fehlerbericht. Auch der Absturz zur Laufzeit scheint ein falsches Verhalten zu sein; Wenn das passieren würde, warum hat der Compiler uns nicht gestoppt? Vielleicht kann jemand anderes rechtfertigen, was Swift in dieser Situation macht. Ich versuche es nur zu erklären.

    
matt 24.11.2014, 22:55
quelle
2

Ich musste UIBarButtonItem für ein Projekt ableiten und der Antwort von Matt folgen, war mehr als genug, mit einem kleinen Unterschied. Ich musste dem Initialisierer Bequemlichkeit hinzufügen, damit der Code funktioniert. In meinem Fall habe ich keine Eigenschaft in meiner Unterklasse.

Hier ist der Code, der für Swift 3 funktioniert, falls es jemandem hilft.

%Vor%     
Nahuel Roldan 01.09.2017 14:56
quelle