Wie soll mein Objective-C Singleton aussehen?
Meiner singleton-accessor-Methode ist in der Regel eine Variante von:
static MyClass *gInstance = NULL;
+ (MyClass *)instance
{
@synchronized(self)
{
if (gInstance == NULL)
gInstance = [[self alloc] init];
}
return(gInstance);
}
Was könnte ich tun um dies zu verbessern?
InformationsquelleAutor der Frage schwa | 2008-09-28
Du musst angemeldet sein, um einen Kommentar abzugeben.
Andere Möglichkeit ist die Verwendung des
+(void)initialize
Methode. Aus der Dokumentation:So dass Sie könnte so etwas wie dieses:
InformationsquelleAutor der Antwort Robbie Hanson
[Quelle]
InformationsquelleAutor der Antwort Ben Hoffstein
Pro meine andere Antwort weiter unten, ich denke, Sie tun sollten:
InformationsquelleAutor der Antwort Colin Barrett
Seit Kendall gepostet eine threadsicher singleton, die versucht zu verhindern, sperren Kosten, ich dachte, ich würde werfen, einer als gut:
Okay, lassen Sie mich erklären, wie das funktioniert:
Schnelle Fall: In der normalen Ausführung
sharedInstance
bereits festgelegt wurde, so dass diewhile
Schleife wird nie ausgeführt und die Funktion gibt nach einfach Tests für die Variablen der Existenz;Slow Fall: Wenn
sharedInstance
nicht vorhanden ist, dann wird eine Instanz zugeordnet ist, kopiert und in es mit Compare And Swap ('CAS');Plead Fall: Wenn zwei threads, die beide versuchen, rufen Sie
sharedInstance
gleichzeitig UNDsharedInstance
nicht zur gleichen Zeit existieren, dann werden Sie beide initialisieren neuer Instanzen der singleton-und versuchen zu CAS in die richtige position. Je nachdem, was der eine gewinnt, der CAS wird sofort, je nachdem was man verliert, löst die Instanz, die es nur reserviert und gibt die (jetzt eingestellt)sharedInstance
. Die einzelnenOSAtomicCompareAndSwapPtrBarrier
fungiert als sowohl eine schreib-Barriere für die Einstellung thread-und eine lese-Barriere aus dem Test-thread.InformationsquelleAutor der Antwort Louis Gerbarg
InformationsquelleAutor der Antwort
Edit: Diese Implementierung wurde mit ARC. Bitte haben Sie einen Blick auf Wie implementiere ich ein Objective-C singleton ist kompatibel mit ARC? für die korrekte Umsetzung.
Alle Implementierungen von initialisieren gelesen habe ich in anderen Antworten teilen sich einen gemeinsamen Fehler.
Die Apple-Dokumentation empfehlen Ihnen, überprüfen Sie die Klassenart an, in Ihrer initialize-block. Da Unterklassen rufen Sie die initialize standardmäßig. Es existiert eine nicht-offensichtliche Fall, wo Unterklassen erstellt werden können, indirekt durch die KVO. Wenn Sie fügen Sie die folgende Zeile in einer anderen Klasse:
Objective-C wird implizit erstellen Sie eine Unterklasse von MySingletonClass, resultierend in einer zweiten Auslösung von
+initialize
.Können Sie denken, dass Sie sollten implizit doppelte Initialisierung in Ihrer init-block als solche:
Aber Sie Schießen sich in den Fuß, oder noch schlimmer für einen anderen Entwickler die Gelegenheit, um zu Schießen selbst in den Fuß.
TL;DR, hier ist meine Umsetzung
(Ersetzen ZAssert mit unseren eigenen Behauptung makro; oder einfach nur NSAssert.)
InformationsquelleAutor der Antwort lorean
Einer gründlichen Erklärung des Singleton-makro-code ist auf dem blog von Kakao Mit Liebe
http://cocoawithlove.com/2008/11/singletons-appdelegates-and-top-level.html.
InformationsquelleAutor der Antwort Matthieu Cormier
Habe ich eine interessante Variante auf sharedInstance, ist thread-sicher, aber nicht gesperrt wird nach der Initialisierung. Ich bin noch nicht sicher genug, es zu ändern, die top-Antwort, wie gewünscht, aber ich es für die weitere Diskussion:
InformationsquelleAutor der Antwort Kendall Helmstetter Gelner
Kurze Antwort: Fabelhaft.
Lange Antwort: so Etwas wie....
Lesen Sie die Versand/einmal.h-header zu verstehen, was Los ist. In diesem Fall wird die header-Kommentare sind mehr anwendbar, als die docs oder die man-Seite.
InformationsquelleAutor der Antwort quellish
Habe ich gerollt singleton in einer Klasse, so können andere Klassen Erben die singleton-Eigenschaften.
Singleton.h :
Singleton.m :
Und hier ist ein Beispiel einer Klasse, Sie werden wollen, singleton.
Die einzige Einschränkung, die über die Singleton-Klasse ist, dass es NSObject Unterklasse. Aber die meiste Zeit nutze ich singletons in meinem code sind Sie in der Tat NSObject Unterklassen, so dass diese Klasse wirklich erleichtern mein Leben und machen code sauberer.
InformationsquelleAutor der Antwort obscenum
Diese funktioniert in einem nicht-garbage-Umgebung auch.
InformationsquelleAutor der Antwort lajos
Shouln ' T diesem werden threadsicher sind und vermeiden Sie die teure sperren, nachdem der erste Anruf?
InformationsquelleAutor der Antwort Jompe
Hier ist ein makro , die ich zusammen gestellt habe:
http://github.com/cjhanson/Objective-C-Optimized-Singleton
Es basiert auf hier die Arbeit von Matt Gallagher
Aber die änderung der Implementierung zu verwenden method swizzling, wie hier beschrieben, durch Dave MacLachlan von Google.
Ich begrüße Kommentare /Beiträge.
InformationsquelleAutor der Antwort CJ Hanson
Wie etwa
So vermeiden Sie die Synchronisierung Kosten nach der Initialisierung?
InformationsquelleAutor der Antwort Tony
Für eine eingehende Diskussion des singleton pattern in Objective-C, schau mal hier:
Mit dem Singleton-Pattern in Objective-C
InformationsquelleAutor der Antwort Fred McCann
KLSingleton
InformationsquelleAutor der Antwort kevinlawler
Die Sie nicht synchronisieren möchten, auf sich selbst... Da ist das selbst-Objekt existiert noch nicht! Sie am Ende die Sperre einer temporären id-Wert. Sie wollen sicherstellen, dass niemand anderes ausführen können Klassenmethoden ( sharedInstance, alloc, allocWithZone:, etc ), so müssen Sie zur Synchronisierung auf das class-Objekt statt:
InformationsquelleAutor der Antwort
Wollte nur raus aus diesem hier, so habe ich nicht zu verlieren. Der Vorteil an diesem ist, dass es nutzbar im InterfaceBuilder, das ist ein großer Vorteil. Dieser stammt aus einer anderen Frage, die ich fragte:
InformationsquelleAutor der Antwort Dan Rosenstark
InformationsquelleAutor der Antwort user370199
Ich weiß, es gibt eine Menge von Kommentaren auf diese "Frage", aber ich sehe nicht viele Menschen, die darauf hindeutet, mit einem makro zu definieren, das singleton. Es ist wie ein gemeinsames Muster, und ein makro vereinfacht das singleton.
Hier sind die Makros die ich schrieb, basiert auf mehreren Objc-Implementierungen, die ich gesehen habe.
Singeton.h
Anwendungsbeispiel:
MyManager.h
MyManager.m
Warum eine interface-makro, wenn es fast leer ist? Code Konsistenz zwischen den header-und code-Dateien, Wartbarkeit, falls Sie möchten, fügen Sie mehr automatische Methoden oder ändern Sie es um.
Ich bin mit der initialize-Methode zu erstellen, die das singleton verwendet wird (in der beliebteste Antwort hier (zum Zeitpunkt des Schreibens).
InformationsquelleAutor der Antwort Nate
Mit Objective-C-Klasse-Methoden, können wir nur vermeiden Sie die Verwendung des singleton-Muster der üblichen Weise aus:
:
durch das einwickeln der Klasse innerhalb einer anderen Klasse nur, dass Klasse Methodenso gibt es keine chance, versehentlich doppelt erstellt Instanzen, da wir nicht die Schaffung einer Instanz!
Schrieb ich einen ausführlicheren blog hier 🙂
InformationsquelleAutor der Antwort chunkyguy
Erweitern das Beispiel von @robbie-hanson ...
InformationsquelleAutor der Antwort JJD
Meine Art ist einfach so:
Wenn das singleton ist schon initialisiert die LOCK-block wird nicht betreten werden. Der zweite check if(!initialisiert) ist, um sicherzustellen, es ist noch nicht initialisiert, wenn der aktuelle thread erwirbt das SCHLOSS.
InformationsquelleAutor der Antwort TienDC
Ich habe nicht alles durch gelesen die Lösungen, so vergebt, wenn der code redundant ist.
Dies ist die thread-sichere Implementierung meiner Meinung nach.
InformationsquelleAutor der Antwort Zolt
Normalerweise verwende ich code, der etwa ähnlich wie in Ben Hoffstein s Antwort (die ich auch habe aus der Wikipedia). Ich benutze es aus den genannten Gründen von Chris Hanson in seinem Kommentar.
Aber manchmal habe ich ein Bedürfnis, ein singleton in einer Feder, und in diesem Fall benutze ich folgende:
Lasse ich die Umsetzung von
-retain
(etc.) für den Leser, obwohl der obige code ist alles was Sie brauchen in ein garbage Collection-Umgebung.InformationsquelleAutor der Antwort Gregory Higley
Die akzeptierte Antwort, obwohl es kompiliert, ist falsch.
Pro Apple-Dokumentation:
... Sie können einen ähnlichen Ansatz zum synchronisieren der Klasse Methoden der zugehörigen Klasse mit dem Class-Objekt, das anstelle des selbst.
Auch bei Verwendung von selbst funktioniert, sollte es nicht zu und das sieht aus wie ein copy und paste Fehler von mir.
Die richtige Implementierung für eine Klasse factory-Methode wäre:
InformationsquelleAutor der Antwort deleted_user