4 Stimmen

Schnittstellen-Generator Kodierung

Gemäß der Dokumentation von Apple instanziiert Interface Builder Objekte, die dann zur Entwurfszeit serialisiert und in eine NIB/XIB-Datei verpackt werden. Zur Laufzeit wird der gesamte Objektgraph über initWithCoder: deserialisiert.

Hier ist die Dokumentation:

View-Instanzen, die in Interface Builder erstellt werden, rufen nicht initWithFrame: auf, wenn ihre NIB-Dateien geladen werden, was oft zu Verwirrung führt. Bedenken Sie, dass Interface Builder ein Objekt archiviert, wenn es eine NIB-Datei speichert, sodass die View-Instanz bereits erstellt wurde und initWithFrame: bereits aufgerufen wurde.

Da die Objekte über initWithCoder: instanziiert werden, dachte ich, dass der Objektgraph über sein Gegenstück encodeWithCoder: serialisiert wird. Betrachten Sie jedoch den folgenden Code:

@interface CustomView : UIView
@end

@implementation CustomView

-(id)initWithCoder:(NSCoder *)aDecoder{
    if(self = [super initWithCoder:aDecoder]){
        NSNumber * n = [aDecoder decodeObjectForKey:@"DummyKey"];
        NSLog(@"%@", n);
    }
    return self;
}

-(void)encodeWithCoder:(NSCoder *)aCoder{
    [super encodeWithCoder:aCoder];
    [aCoder encodeObject:@YES forKey:@"DummyKey"];
}

@end

Wenn ich dieses CustomView in einem Storyboard in Interface Builder platziere, wird "(null)" anstelle von "YES" gedruckt. Warum passiert das? Wie serialisiert Interface Builder den Objektgraph? Habe ich die Dokumentation falsch interpretiert?

1voto

KudoCC Punkte 6852

encoderWithCoder: Methode wird nicht aufgerufen, weil zur Laufzeit, wenn XCode den Objektgraphen in das Xib codiert, Ihre encoderWithCoder: Methode nicht aufgerufen werden kann.

Wie serialisiert Interface Builder den Objektgraphen?

Wenn Sie das Xib als Quellcode öffnen, können Sie es so sehen:

Wir sehen, dass das Xib nur den nicht standardmäßigen Wert des Objekts und die Beziehungen zwischen ihnen speichert.

Das Xib ist ein UIViewController und hat nur zwei UI-Objekte, eines ist die Ansicht des UIViewControllers, das andere ist seine Unteransicht, nennen wir sie mysubview und spricht darüber, wie XCode mysubview archiviert.

Ich habe die backgroundColorframe- und autoresizingMask-Eigenschaft von mysubview geändert, nehmen wir die backgroundColor-Eigenschaft als Beispiel, die backgroundColor-Eigenschaft wird als "color key="backgroundColor" white="0.0" alpha="1" colorSpace="calibratedWhite"" gespeichert. Es wird die Hintergrundfarbe von mysubview archivieren.

Das Xib archiviert nur die Hintergrundfarbe und die autoresizingMask- und frame-Eigenschaft des mysubview-Objekts, und beim Laden des Xibs wird die initWithCoder-Methode der UIView aufgerufen. In der Methode wird das UIColor-Objekt für den Schlüssel @"backgroundColor" und CGRect für den Schlüssel @"frame" und UIViewAutoresizing für den Schlüssel @"autoresizingMask" abgerufen, alle anderen Eigenschaften der UIView erhalten ihren standardmäßigen Wert.

- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder] ;
    UIColor * backgroundColor = [aDecoder decodeIntegerForKey:@"backgroundColor"] ;
    if (backgroundColor) {
        self.backgroundColor = backgroundColor ;
    } else {
        self.backgroundColor = $(defaultColor) ; // wenn kein Schlüssel im Xib vorhanden ist, wird der Standardwert verwendet.
    }
    // mehr...
    return self ;
}

Das ist eine gute Frage und regt mich zum Nachdenken an.

0voto

Sulthan Punkte 123129

Interface Builder verwendet Ihren Code nicht, um Xibs zu generieren. Ganz einfach. encodeWithCoder wird vom Interface Builder nie aufgerufen. Der Interface Builder führt Ihren Code nicht aus.

0voto

Retro Punkte 3985

In einfachen Worten, wenn Sie Ihr Objekt in Xib oder Storyboard erstellen, können initWithFrame und initWithCoder nicht von Ihnen überschrieben werden, sie werden vom Framework aufgerufen und erstellen die Objekteigenschaft aus Xib oder Storyboard.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X