Was genau ist ein sogenannter „Klassencluster“ in Objective-C?

91

Ich habe gelesen, dass NSArray so etwas ist. Klingt schwer. Ich habe hier auf meinem Schreibtisch 7 wirklich dicke Bücher über Objective-C, Cocoa und C. Keiner von ihnen erwähnt Class Cluster überhaupt, zumindest kann ich es nicht im Index am Ende der Bücher finden. Also, was ist das?

offener Frosch
quelle
Hoppla, das nächste Mal werde ich darüber nachdenken, einen Link für diesen Begriff hinzuzufügen. Wenn Sie die Antwort auf Ihre vorherige Frage kommentiert hätten, hätte ich dort geantwortet.
Georg Fritzsche
2
FWIW: Vor kurzem (Dezember 2013) empfahl Apple die Verwendung von Klassenclustern, um die Abwärtskompatibilität mit iOS 6 unter iOS 7 zu gewährleisten. Dies war in den Apple Tech Talks 2013 / Berlin in der Sitzung "Architecting Modern Apps, Part 2". Apple gab bekannt, dass sie kurz nach der letzten Veranstaltung (17. Dezember) Videos der Sitzungen veröffentlichen werden. Vielleicht hilft dies, Klassencluster im tatsächlichen Kontext der Änderungen an iOS 6/7 zu verstehen.
Brainray

Antworten:

42

Von Apple docs ... . Kurz gesagt, es handelt sich um ein Entwurfsmuster, das im Foundation-Framework verwendet wird, weshalb es wahrscheinlich nicht in ObjC-Büchern erwähnt wird.

Ein Klassencluster ist eine Architektur, die eine Reihe privater, konkreter Unterklassen unter einer öffentlichen, abstrakten Oberklasse gruppiert. Die Gruppierung von Klassen auf diese Weise bietet eine vereinfachte Oberfläche für den Benutzer, der nur die öffentlich sichtbare Architektur sieht.

Echo
quelle
1
roflmao. Vielen Dank. Ich werde das nächste Mal googeln. dachte, wenn es nicht in meinen fetten Büchern ist, kann es nur auf deinen Köpfen sein;)
openfrog
1
In diesem Link fehlt lediglich eine Erklärung, wie Sie die Implementierung für ARC am besten ändern können.
Hyperbole
193

Ich weiß nicht, worauf sich das CDP bezieht, auf das Steve verwiesen hat, aber im Grunde ist der Objective-C-Klassencluster ein Konstrukt, das die Implementierung des abstrakten Factory- Musters unterstützt.

Die Idee ist einfach : Sie möchten eine Factory-Schnittstelle (Cluster) bereitstellen, die mit minimaler Beschreibung eine bestimmte konkrete Instanz eines Factory-Objekts herstellt und zurückgibt, die dem Verhalten der von der Factory-Schnittstelle (Cluster) beschriebenen Clusterfamilie entspricht.

Ein einfaches konkretes Beispiel : Dieses Beispiel bietet eine Lachfabrik, in der konkrete Klassen bestimmter Lachtypen (z. B. Guffaw, Giggle) hergestellt werden. Achten Sie auf die Methode Laugh initWithLaughter : .

In Laugh.h:

#define kLaughWithGuffaw  1
#define kLaughWithGiggle  2

@interface Laugh: NSObject {}
- (Laugh *) initWithLaughter:(NSUInteger) laughterType;
- (void) laugh;
@end

In Laugh.m:

@interface Guffaws:Laugh {}
- (void) laugh;
@end

@interface Giggles:Laugh {}
- (void) laugh;
@end

@implementation Laugh
- (Laugh *) initWithLaughter:(NSUInteger) laugherType {
    id instanceReturn=nil;
    ; // Removed for ARC [self release]
    if ( laughterType == kLaughWithGuffaw )
        instanceReturn = [[Guffaws alloc]init];
    else if( laughterType == kLaughWithGiggle )
        instanceReturn = [[Giggles alloc]init];
    else
        ; // deal with this
    return instanceReturn;
}

- (void) laugh {
    NSLog(@"Humbug");
}
@end

@implementation Guffaws
    - (void) laugh {
        NSLog(@"OH HA HA HOWAH HA HA HA");
    }
@end

@implementation Giggles
    - (void) laugh {
        NSLog(@"Tee hee");
    }
@end
Frank C.
quelle
24
Während die anderen Antworten gut waren, um Links zu Dokumenten und Büchern bereitzustellen, gefällt mir das, weil es schön und einfach ist, zu sehen, wie man das tatsächlich macht. Danke
Jamone
Dieses Beispiel ist gut, aber in einem typischen Factory-Muster sind die Unterklassen öffentlich. In einem Klassencluster sind die Unterklassen privat. developer.apple.com/library/ios/documentation/general/…
maxpower
1
@ AdriàNavarro Sie sind nach außen nicht sichtbar, da sie in der deklariert sind .m-file.
Hfossli
4
(1) Wie sicher ist es, sich in einer initMethode freizugeben und etwas anderes zurückzugeben? Gibt es Codebeispiele von Apple, in denen dies geschieht? (2) Außerdem erstellen Sie vermutlich eine Instanz mit Code wie [[Laugh alloc] initWithLaughter:kLaughWithGiggle]. Beachten Sie, wie Laughunnötig zugewiesen wird, da es sofort nach diesem Aufruf freigegeben wird. Warum so, wenn Sie eine Klassenmethode erstellen können, [Laugh laughWithLaughter:kLaughWithGiggle]die Ihnen alle Vorteile privater Unterklassen bietet und gleichzeitig die obigen Probleme 1 und 2 vermeidet?
Sinnvoll
1
@Senseful Du hast recht. +allocGibt im wirklichen Leben eine Singleton-Factory-Klasse zurück, die die verschiedenen -initWith:Methoden implementiert . Die -initWith:Methoden der Factory-Klasse sind dann dafür verantwortlich, eine konkrete Unterklasse basierend auf den angegebenen Methodenparametern zuzuweisen und zu initialisieren, falls erforderlich, oder in einigen Fällen überhaupt nichts zuzuweisen (z. B. -[NSString initWithString:]). Sie können es versuchen , auf den Rückgabewert von Inspektion +[NSString alloc], +[NSArray alloc]usw.
Darren
25

Aus der Programmierung in Ziel c von Stephen Kochan auf Seite 498 im Glossar, Cluster:

Eine abstrakte Klasse, die eine Reihe privater konkreter Unterklassen gruppiert und dem Benutzer über die abstrakte Klasse eine vereinfachte Schnittstelle bietet.

t011phr33
quelle
5
+1 Für das Zitieren einer Antwort aus einem Objective-C-Buch, insbesondere angesichts der ursprünglichen Frage. Das ist auch ein gutes Buch.
Quinn Taylor
(+1) für die hervorragende Definition. Das Problem, das ich habe, wenn ich dies als "Factory" -Muster bezeichne, ist, dass sich ein solcher Name nur auf die Erstellung von Objekten konzentriert, nicht auf die Interaktionen der privaten Unterklassen unter der Haube, wie sie von der abstrakten Oberklasse verwaltet werden. Selbst diese Oberklasse als "abstrakt" zu bezeichnen, könnte irreführend sein, da sie tatsächlich (intern) von ihren eigenen Unterklassen abhängt und daher keine normale abstrakte Klasse ist, die im Allgemeinen nichts über ihre Unterklassen weiß.
Devios1
18

Klassencluster bieten eine einzige öffentliche Schnittstelle zu einer Gruppe konkreter, privater Unterklassenimplementierungen. Ein Objective-C-Programmierer verwendet Klassencluster häufig und erkennt dies selten - und das ist der springende Punkt eines Klassenclusters. Die Aufgabe eines Klassenclusters besteht darin, die Komplexität der Implementierungsdetails hinter einer öffentlichen Schnittstelle zu verbergen.

Viele der Foundation-Klassen sind Klassencluster wie NSString, NSArray, NSDictionary und NSNumber. Wenn Sie [NSString stringWithFormat:]den Klassencluster aufrufen , erhalten Sie eine konkrete Klasse, die die NSStringSchnittstelle implementiert . Es könnte eine sein NSConcreteString, NSCFString,NSFooBarString usw. , die die Klasse Cluster gibt Ihnen auf den Konstruktor basiert oder initializer Sie anrufen und die Argumente.

Aus diesem Grund sind Klassencluster eines der leistungsfähigsten Konzepte in der Objective-C-Programmierung.

  • Sehr einfach zu implementieren
  • Es ist einfach, die zugrunde liegende Implementierung zu ändern, ohne den Code zu ändern, der sie aufruft.
  • Einfache Bereitstellung verschiedener konkreter Implementierungen zur Laufzeit (z. B. Testressourcen oder Scheinobjekte)
  • Aus diesem Grund einfach zu testen und umzugestalten

Wenn Sie aus anderen Sprachen kommen, sind Sie möglicherweise mit den Gang of Four-Mustern vertraut. Klassencluster enthalten Elemente sowohl der abstrakten Fabrik als auch der Fassadenmuster.

In der öffentlichen Dokumentation von Apple werden Klassencluster (und deren Implementierung und Erweiterung) ausführlich behandelt. Leider habe ich festgestellt, dass dieses und andere kakaospezifische Muster für viele iOS-Entwickler ein blinder Fleck sind.

Kakaokernkompetenzen: Klassencluster

Kakao-Grundlagenhandbuch: Klassencluster

Beispiele für die Implementierung eigener Klassencluster finden Sie auf GitHub

quellish
quelle
7

Der NSArray-Klassencluster ist kein "Schwergewicht", sondern eine Möglichkeit, eine beliebige Anzahl von Implementierungen einer Array-Klasse zu verwenden, ohne dass Ihr Code die jeweilige Implementierung kennt oder sich darum kümmert. Unter der Haube befinden sich konkrete Unterklassen von NSArray, die für verschiedene Anwendungsfälle geeignet sind, z. B. große, spärliche Arrays oder Arrays mit einer bestimmten Anzahl von Elementen, die zur Kompilierungszeit bekannt sind.

NSArray, NSString und NSNumber sind die Klassencluster, auf die Sie am häufigsten stoßen.

NSResponder
quelle
6
Ironischerweise wird in der Praxis immer nur noch eine konkrete Klasse pro Cluster verwendet - NSCF {Array | String | Number} - und die Implementierungsänderungen sind intern für diese Klasse. Soweit ich weiß, jedenfalls. Sogar NSArray- und NSMutableArray-Instanzen zeigen dieselbe Klasse an.
Chuck
1
@Chuck - wie kann das sein? Wenn ein NSMutableArray und ein NSArray sich als dieselbe Klasse melden würden, würden sie nicht [myArray isKindOfClass:[NSMutableArray class]]JA zurückgeben, obwohl dies nicht der Fall sein sollte?
Robert
1
@ Robert: Und tatsächlich war das zum Zeitpunkt meines Kommentars der Fall. Heutzutage hat Apple NSCFArray durch __NSArrayM und __NSArrayI ersetzt, daher denke ich, dass dies nicht mehr der Fall ist, aber ich würde mich trotzdem nicht wohl fühlen, da sie es immer wieder ändern könnten.
Chuck