5

Bin in etwas Interessantes gelaufen, möchte wissen, ob ich etwas falsch mache oder ob das das richtige Verhalten ist.Automatisches Laden von XIB für UITableViewController

Ich habe einen benutzerdefinierten UITableViewController. Ich nahm an (erster Fehler), wenn Sie als solche zu initialisieren:

[[CustomTableController alloc] init]; 

es automatisch von einem XIB mit dem gleichen Namen laden würde, CustomTableController.xib, wenn es im gleichen Verzeichnis und so.

JEDOCH

Dies funktioniert nicht; lädt das XIB nicht. ABER, wenn ich die Elternklasse meines Controllers von 'UITableViewController' zu 'UIViewController' ändere, FUNKTIONIERT JEDES WERK!

Aufruf:

[[CustomTableController alloc] init]; 

lädt die Steuerung und Blick aus meinem xib.

Mache ich etwas falsch? Ist das ein Fehler? Erwartetes Verhalten?

Antwort

26

Die meisten Klassen in Cocoa Touch listen einen "designed initializer" auf, den Sie von Ihren init-Methoden aufrufen sollten, wenn Sie sie unterklassifizieren. Wenn Sie eine benutzerdefinierte Klasse erstellen, empfiehlt es sich, in der Dokumentation nach dem angegebenen Initialisierer für Ihre Oberklasse zu suchen. Wenn Sie die Klasse mit einem anderen Initialisierer aus einer allgemeineren Oberklasse initialisieren (was Sie tun, indem Sie in diesem Fall - [NSObject init] aufrufen), berauben Sie Ihre direkte Oberklasse ihrer Gelegenheit, seinen Zustand ordnungsgemäß zu initialisieren. Manchmal kann man damit durchkommen. Oft kannst du nicht.

In der Dokumentation von UIViewController steht, dass der Initialisierer - initWithNibName:bundle: - als Initializer bezeichnet wird. Wenn Sie diese Methode mit einem Nil-Nib-Namen aufrufen, sucht sie nach einer Nib, die Ihrem Klassennamen entspricht. Das Verhalten von -init ist für UIViewController nicht dokumentiert. Basierend auf dem Verhalten, das Sie sehen, scheint es, als könnte es [self initWithNibName:nil bundle:nil] aufrufen, aber es wäre sicherer, initWithNibName:bundle: direkt zu rufen, anstatt sich auf dieses undokumentierte Verhalten zu verlassen.

UITableViewController definiert nur einen einzelnen Initialisierer, -initWithStyle: (obwohl diese Methode nicht als designierter Initialisierer angegeben wird). Diese Methode initialisiert Ihren UITableViewController ohne Verwendung einer Schreibfeder, was normalerweise gut ist. Da Sie keine Subviews zu einem UITableView hinzufügen, ist es normalerweise nicht viel zu gewinnen, wenn Sie Ihren UITableViewController über eine Nib konfigurieren.

Wenn Sie Ihren UITableViewController dennoch über eine Feder konfigurieren möchten, wird in der Dokumentation angegeben, dass wir -initWithStyle: umgehen und die initWithNibName:bundle:-Methode von UIViewController aufrufen können. Hier ist, was die Dokumentation sagt uns, wie unsere UITableView und seine Steuerung werden jeweils initialisiert werden:

  • Wenn eine Nib-Datei über die initWithNibName:bundle: Methode angegeben wird (die von dem übergeordneten Klasse UIViewController erklärt wird), UITableViewController lädt die Tabellenansicht, die in der NIB-Datei archiviert ist. Andernfalls wird ein nicht konfiguriertes UITableView-Objekt mit den korrekten Dimensionen und der Autoresize-Maske erstellt. Sie können auf diese Ansicht über die Eigenschaft tableView zugreifen.

  • Wenn eine NIB-Datei mit der Tabellenansicht geladen wird, werden die Datenquelle und der Delegat zu den in der NIB-Datei definierten Objekten (falls vorhanden). Wenn keine NIB-Datei angegeben ist oder wenn die NIB-Datei keine Datenquelle oder keinen Delegaten definiert, setzt UITableViewController die Datenquelle und den Delegaten der Tabellensicht auf self.

Zusammenfassend ist die Dokumentation für die meisten Cocoa Touch Klassen entweder einen einzelnen bestimmten Initialisierung oder eine Handvoll initializers angeben, die Sie sicher von Ihrem Subklassen aufrufen können. Beziehen Sie sich immer auf die Dokumentation für Ihre Oberklasse, um herauszufinden, welchen Initialisierer Ihre Unterklasse aufrufen sollte.

+0

Ausgezeichnete Antwort, danke! Ich wünschte, ich könnte dir mehr Punkte geben. – ACBurk

+0

Meine Anwendung stürzt ab, wenn ich ein xib mit einem UIView darin und einem UITableView darin erstelle und versuche, dieses xib mit initWithNibName zu laden, wie du es beschreibst. Es klagt: "- [UITableViewController loadView] hat die" XXXXXXTableViewController "-Nib geladen, aber kein UITableView bekommen. ' Ich habe auch versucht, die Root-Ansicht des Xib nur ein UITableView zu sein, aber wenn ich das tue lädt die App aber keine der Anpassungen, die ich an der Tabelle in der App gemacht habe.:/ –

+0

Ich dachte, ich würde verrückt wenn es schien, als ob es Nibs mit dem gleichen Namen wie die Klasse geladen hatte Sehr gute Erklärung – zekel

Verwandte Themen