wake-up-neo.net

Klassenerweiterung vs. Klassenkategorie

Klassenerweiterungen @interface Class () sind wesentlich leistungsfähiger und können Variablen in die Klasse einfügen. Kategorien @interface Class (Category) können nicht. 

Welche anderen Unterschiede gibt es und wann sollte man eine Kategorie über eine Klassenerweiterung verwenden?

75
David

Der Hauptunterschied besteht darin, dass der Compiler bei einer Erweiterung erwartet, dass Sie die Methoden innerhalb Ihres @implementation-Hauptcodes implementieren, wohingegen Sie bei einer Kategorie einen separaten @implementation-Block haben. Sie sollten also eigentlich nur eine Erweiterung oben in Ihrer .m-Datei verwenden (der einzige Ort, an dem Sie sich übrigens mit Ivars beschäftigen sollten) - es soll nur eine Erweiterung sein.

83
jtbandes

Eine Klassenerweiterung weist einige Ähnlichkeiten mit einer Kategorie auf. Sie kann jedoch nur zu einer Klasse hinzugefügt werden, für die Sie den Quellcode zur Kompilierzeit haben (die Klasse wird zur gleichen Zeit wie die Klassenerweiterung kompiliert). Die von einer Klassenerweiterung deklarierten Methoden sind im Block @implementation für die ursprüngliche Klasse implementiert, sodass Sie beispielsweise keine Klassenerweiterung für eine Framework-Klasse deklarieren können, beispielsweise eine Cocoa- oder Cocoa Touch-Klasse wie NSString.

Die Syntax zum Deklarieren einer Klassenerweiterung ähnelt der Syntax für eine Kategorie und sieht folgendermaßen aus:

@interface ClassName ()
@end

Da in 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 deklarieren, wie folgt:

@interface XYZAnimal () {
    id _someCustomInstanceVariable;
}
...
@end

IMHO ist es am besten, Klassenerweiterungen als private Schnittstelle zu einer Klasse zu betrachten. Die primäre Schnittstelle (in Ihrer .h-Datei) fungiert als öffentliche Schnittstelle, die den Verhaltensvertrag der Klasse mit anderen Klassen definiert.

Verwenden Sie Klassenerweiterungen zum Ausblenden privater Informationen 

Klassenerweiterungen werden häufig verwendet, um die öffentliche Schnittstelle um zusätzliche private Methoden oder Eigenschaften zur Verwendung in der Implementierung der Klasse selbst zu erweitern. Es ist zum Beispiel üblich, eine Eigenschaft als schreibgeschützt in der Schnittstelle zu definieren, aber als Readwrite in einer über der Implementierung deklarierten Klassenerweiterung, damit die internen Methoden der Klasse den Eigenschaftswert direkt ändern können.

Beispielsweise kann die XYZPerson-Klasse eine Eigenschaft namens uniqueIdentifier hinzufügen, die dazu dient, Informationen wie eine Sozialversicherungsnummer in den USA zu verfolgen.

Normalerweise erfordert es eine Menge Papierkram, um einer Person in der realen Welt einen eindeutigen Bezeichner zuzuweisen. Daher kann die Klassenschnittstelle der XYZPerson-Klasse diese Eigenschaft als schreibgeschützt deklarieren und eine Methode bereitstellen, die die Zuweisung eines Bezeichners anfordert:

@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 erneut zu deklarieren, die oben in der Implementierungsdatei für die Klasse definiert ist:

@property (readwrite) NSString *uniqueIdentifier;

Hinweis: Das Readwrite-Attribut ist optional, da es die Standardeinstellung ist. Sie können es zur Klarheit verwenden, wenn Sie eine Eigenschaft neu deklarieren.

22
John Doe

Kategorien sind eine Funktion der Objective-C-Sprache, mit der Sie einer vorhandenen Klasse neue Methoden hinzufügen können. Erweiterungen sind ein Sonderfall von Kategorien, mit denen Sie Methoden definieren können, die im Hauptimplementierungsblock implementiert werden müssen.

Private Deklarationen können in Klassenerweiterungen enthalten sein. Dies sind hauptsächlich einige Eigenschaften, da wir vor dem Aufruf keine Methode deklarieren müssen.

5
Julie Yu

ios-Erweiterung ähnlich wie c #, Java Abstract Class oder Interface
ios-Kategorie ähnlich der c # -Klassenerweiterung

0
Add080bbA