Optionale Bindung ist erfolgreich, wenn dies nicht der Fall ist

8

Dies habe ich als mögliche Lösung für angezeigt, um die Controller-Hierarchie in Swift (leicht modifiziert):

%Vor%

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:

%Vor%

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.

  • Ändern der Build-Konfiguration von "Debug" auf "Release" macht auch die Methode funktioniert wie erwartet. (Ich habe das bisher nur im iOS Simulator getestet.)

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.

    
Martin R 14.09.2014, 21:07
quelle

1 Antwort

3

Wenn Sie versuchen, ein Objekt vom Typ " UINavigationController " in einem Playground unter " UICollectionViewController " bedingt zu werfen:

%Vor%

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%     
vacawama 15.09.2014, 02:13
quelle

Tags und Links