2016-06-04 4 views
0

Ich habe eine UIViewController, die ich in einem Storyboard für eine Weile ohne Probleme hatte. Als meine Anwendung wuchs und ich diesen View-Controller an immer mehr Orten verwendete, wurde mir klar, dass ich ihn wahrscheinlich portabler machen sollte, anstatt so viele Übergänge von überall her zu haben. Ich habe solche Splits schon einmal gemacht, also habe ich getan, was ich für logisch hielt. Ich habe diesen View-Controller ausgewählt, ausgeschnitten und in eine leere .xib-Datei eingefügt. jeden Aufruf performSegueWithIdentifier einer zu init(nibName:bundle:) und presentViewController Nach dem Wechsel, erhalte ich einen Absturz, mit einem Objekt unerwartet null in viewDidLoad() ...UIViewController initWithNibNamed: Bündel: zwei Objekte initialisiert?

ich den Wert dieses Objekts nach jeder init (...) Aufruf gefunden, nur bevor Sie den View-Controller präsentieren. Das Nullobjekt wird von viewDidLoad() aufgerufen. Das ist ein Problem. Ich habe das nur eingestellt, und jetzt ist es weg ?!

overrode ich die init (...) -Methode, und festgestellt, dass self in init(nibName:bundle:) nicht die gleiche Speicheradresse wie self in viewDidLoad() hat. Auch seltsam.

overrode ich den anderen init() Methoden und festgestellt, dass, nachdem ich meine Ansicht präsentieren nennen, ist mein Objekt wieder über init(coder:) instanziert werden! Die self hier ist genau die self, wo meine Eigenschaft ist nicht gefunden!

Der einzige Grund, warum ich für init(coder:) sehen bei allen genannt werden, ist, dass ich von einem .xib meiner Sicht bin Laden, aber ich dachte, das in init(nibNamed:bundle:) behandelt wurde? Laut den Dokumenten bekomme ich tatsächlich einen Anruf an init(coder:), wenn ich von einem Storyboard lade, und nicht die erstere ... Es sagt auch, dass die Feder nicht geladen wird, bis die Controller-Ansicht abgefragt wird. Wenn ich es richtig verstehe, sollte meine Ansicht nicht abgefragt werden, bis ich die Ansicht präsentiere. Da der Absturz nur auftritt, wenn ich es präsentiere, stammt das Problem wahrscheinlich daraus.

Ich stecke hier fest. Ich muss diese kontextuellen Informationen immer noch an den View-Controller senden, bevor er präsentiert wird. Ich habe sogar versucht, vor der Präsentation eine Proxy-Klasse zu erstellen, um die Instanziierung und Eigenschafteneinstellung vorzunehmen, aber ich kann diese zweite Instanz immer noch nicht erschüttern! Ich bekomme einen von init(nibName:bundle:), und einen anderen von init(coder:). Keiner wird präsentiert, und letzterer gibt mir einen Null-Objektfehler. Irgendwelche Hilfe überhaupt, um zu verstehen, warum das ist, und wie ich um diesen Fehler (Funktion?) Arbeiten könnte, würde sehr geschätzt werden. Vielen Dank!


aktualisieren:

Aus einer Laune heraus habe ich beschlossen, die View-Controller wieder in das Storyboard, getrennt von der Haupt-Hierarchie einzufügen, und versuchen Sie es durch seine Kennung instanziieren. Es funktionierte! Nicht ganz sicher wie, aber von George hat es funktioniert! Jetzt ist meine Frage: Warum? Was ist so furchtbar böse und tabu über XIBs, die Xcode und iOS mir nicht sagen? Ich bin nicht ein bisschen verwirrt von diesem Verhalten. Ich versuche es weiter mit der .xib, wenn ich nur Xcode davon abhalten soll, mich über Eingangspunkte anzurufen ...

Antwort

1

Ich weiß nicht, was dunkle Magie Xcode macht, aber hier sind zwei Hilfsmethoden, die ich einfach geschrieben habe instanziiere jede Storyboard-VC - du brauchst nur den Storyboard-Namen und den VC-Identifikator (optional, sonst wird der anfängliche VC). Indem ich meine VCs in viele verschiedene Storyboards aufteile, vermeide ich es, mit xibs zu arbeiten, während ich immer noch die Dinge einfach halte. Man lädt es in einen Nav-Controller Ihrer Wahl, der andere gibt es nur von sich selbst zurück:

struct StoryboardHelper { 
///instantiates a VC with (optional) identifier viewController from storyboardName, pushes it to hierarcy of navigationController, and runs setup block on it, animated specifies whether the push is animated 
internal static func showStoryboard(storyboardName: String, viewController: String?, navigationController: UINavigationController, animated: Bool = true, setup: (UIViewController) ->()){ 
    let storyboard = UIStoryboard(name: storyboardName, bundle: nil) 
    let destinationVC = viewController != nil ? storyboard.instantiateViewControllerWithIdentifier(viewController!) : storyboard.instantiateInitialViewController()! 
    setup(destinationVC) 
    navigationController.pushViewController(destinationVC, animated: animated) 
    } 

///instantiates and returns a VC with (optional) identifier viewController from storyboardName 
internal static func instantiateViewControllerFromStoryboard(storyboardName: String, viewController: String?) -> UIViewController{ 
    let storyboard = UIStoryboard(name: storyboardName, bundle: nil) 
    return viewController != nil ? storyboard.instantiateViewControllerWithIdentifier(viewController!) : storyboard.instantiateInitialViewController()! 
    } 
} 
Verwandte Themen