Eine Klassenerweiterung weist eine gewisse Ähnlichkeit mit einer Kategorie auf, kann jedoch nur einer Klasse hinzugefügt werden, für die Sie zur Kompilierungszeit über den Quellcode verfügen (die Klasse wird gleichzeitig mit der Klassenerweiterung kompiliert). Die von einer Klassenerweiterung deklarierten Methoden werden im @ implementierungsblock für die ursprüngliche Klasse implementiert, sodass Sie beispielsweise keine Klassenerweiterung für eine Framework-Klasse wie eine Cocoa- oder Cocoa Touch-Klasse wie NSString deklarieren können.
Die Syntax zum Deklarieren einer Klassenerweiterung ähnelt der Syntax für eine Kategorie und sieht folgendermaßen aus:
@interface ClassName ()
@end
Da in den Klammern kein Name angegeben ist, werden Klassenerweiterungen häufig als anonyme Kategorien bezeichnet.
Im Gegensatz zu regulären Kategorien kann eine Klassenerweiterung einer Klasse eigene Eigenschaften und Instanzvariablen hinzufügen. Wenn Sie eine Eigenschaft in einer Klassenerweiterung wie folgt deklarieren:
@interface XYZAnimal () {
id _someCustomInstanceVariable;
}
...
@end
IMHO ist es am besten, sich Klassenerweiterungen als private Schnittstelle zu einer Klasse vorzustellen. Die primäre Schnittstelle (in Ihrer .h-Datei) fungiert als öffentliche Schnittstelle, die den Verhaltensvertrag der Klasse mit anderen Klassen definiert.
Verwenden Sie Klassenerweiterungen, um private Informationen auszublenden
Klassenerweiterungen werden häufig verwendet, um die öffentliche Schnittstelle um zusätzliche private Methoden oder Eigenschaften zu erweitern, die in der Implementierung der Klasse selbst verwendet werden können. Es ist beispielsweise üblich, eine Eigenschaft als schreibgeschützt in der Schnittstelle, aber als schreibgeschützt in einer über der Implementierung deklarierten Klassenerweiterung zu definieren, damit die internen Methoden der Klasse den Eigenschaftswert direkt ändern können.
Beispielsweise könnte die XYZPerson-Klasse eine Eigenschaft namens uniqueIdentifier hinzufügen, mit der Informationen wie eine Sozialversicherungsnummer in den USA erfasst werden sollen.
Normalerweise ist ein großer Papierkram erforderlich, um einer Person in der realen Welt einen eindeutigen Bezeichner zuzuweisen. Daher kann die XYZPerson-Klassenschnittstelle diese Eigenschaft als schreibgeschützt deklarieren und eine Methode bereitstellen, mit der ein Bezeichner wie folgt zugewiesen werden muss:
@interface XYZPerson : NSObject
...
@property (readonly) NSString *uniqueIdentifier;
- (void)assignUniqueIdentifier;
@end
Damit die XYZPerson-Klasse die Eigenschaft intern ändern kann, ist es sinnvoll, die Eigenschaft in einer Klassenerweiterung neu zu deklarieren, die oben in der Implementierungsdatei für die Klasse definiert ist:
@property (readwrite) NSString *uniqueIdentifier;
Hinweis: Das Attribut readwrite ist optional, da es die Standardeinstellung ist. Sie können es aus Gründen der Übersichtlichkeit beim erneuten Deklarieren einer Eigenschaft verwenden.