Dies habe ich als mögliche Lösung für angezeigt, um die Controller-Hierarchie in Swift
Die Methode sollte die hierarchische Hierarchie der übergeordneten Ansicht durchlaufen und die erste zurückgeben Instanz der angegebenen Klasse oder nil, wenn keine gefunden wird.
Aber es funktioniert nicht, und ich kann nicht herausfinden warum. Die optionale Bindung
markiert mit (XXX)
ist immer erfolgreich , so dass der erste übergeordnete View-Controller zurückgegeben wird
auch wenn es keine Instanz von T
ist.
Dies kann einfach reproduziert werden: Erstellen Sie ein Projekt von der "iOS Master-Detail Application"
Vorlage in Xcode 6 GM, und fügen Sie den folgenden Code zu viewDidLoad()
der
MasterViewController
class:
self
ist ein MasterViewController
(eine Unterklasse von UITableViewController
) und seine
Elternsicht-Controller ist ein UINavigationController
.
In der übergeordneten Ansicht gibt es kein UICollectionViewController
Controller-Hierarchie, damit würde ich die Methode erwarten
gibt nil
zurück und die Ausgabe wird "nicht gefunden".
Aber das ist was passiert:
%Vor% Das ist offensichtlich falsch, weil UINavigationController
keine Unterklasse von ist
%Code%. Vielleicht habe ich einen dummen Fehler gemacht, aber ich konnte ihn nicht finden.
Um das Problem zu isolieren, habe ich auch versucht, es mit meiner eigenen Klasse zu reproduzieren Hierarchie, unabhängig von UIKit:
%Vor%Und raten Sie was? Jetzt funktioniert es wie erwartet! Die Ausgabe ist
%Vor%UPDATE:
Entfernen der Typbeschränkung in der generischen Methode
%Vor%wie von @ POB in einem Kommentar vorgeschlagen, funktioniert wie erwartet.
Ersetzen der optionalen Bindung durch eine "zweistufige Bindung"
%Vor%wie von @ vacawama in seiner Antwort vorgeschlagen, funktioniert auch wie erwartet.
Der letzte Punkt könnte anzeigen, dass dies ein Swift-Compiler- oder Laufzeitfehler ist. Und ich immer noch
kann nicht sehen, warum das Problem mit Unterklassen von UICollectionViewController
auftritt, aber nicht
mit Unterklassen meiner UIViewController
. Deshalb werde ich die Frage offen halten für
während bevor Sie eine Antwort akzeptieren.
UPDATE 2: Dies wurde ab Xcode 7 behoben.
Mit dem letzten Xcode 7
Release Das Problem tritt nicht mehr auf. Die optionale Bindung
BaseClass
in der Methode if let result = parentVC as? T
funktioniert jetzt (und scheitert) wie erwartet, sowohl in der Release- als auch in der Debug-Konfiguration.
Wenn Sie versuchen, ein Objekt vom Typ " UINavigationController
" in einem Playground unter " UICollectionViewController
" bedingt zu werfen:
Sie erhalten diesen Fehler:
Ausführung des Playgrounds fehlgeschlagen:: 33: 16: Fehler: 'UICollectionViewController' ist kein Subtyp von 'UINavigationController' wenn vc = nc wie? UICollectionViewController {
aber wenn Sie stattdessen tun:
%Vor%es druckt "Nein".
Ich schlage also vor:
%Vor%