Eine threadsichere statische Variablen Ziel c
Gibt es eine Möglichkeit in objective C kann ich definieren einer statischen int, das ist thread-sicher?
zum Beispiel, wenn ich die Klasse genannt-Sitzung:
static unsigned int session_id = 1000;
- (int) generateSessionID{
return session_id++;
}
Ich bin konstruieren session-Objekte aus verschiedenen threads, jedes session-Objekt
sollte eine eindeutige id.
- Müssen Sie irgendeine Art von sperren Semantik. Das Problem ist Sie wollen die operation atomar. Aber Bedenken Sie, dass "++" ist nicht atomar, es ist ein paar Operationen auf einmal.
- möglich ist dann, surround meiner Rückkehr session_id++ mit synchronized(self){return session_id++}. Allerdings bin ich nicht sicher, ob diese sperren, die Klasse oder das Objekt, das es selbst.
- wie geschrieben, es würde sperren Sie die Instanz, nicht die Klasse (nicht das, was Sie wollen). Vielleicht "
@synchronized([self class])
"? - Gelhar: Nein, synchronisieren nicht auf
[self class]
weil Instanzen von Unterklassen würde synchronisieren, die auf unterschiedliche Objekte der Klasse. Synchronisieren auf eine explizite Klasse z.B.[MyClass class]
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn Sie im Gespräch Kakao, den mutex-Funktionen wird zur Verfügung gestellt von
NSLock
undNSRecursiveLock
.Um richtig zu schützen Sie nicht-atomaren Ressourcen, die Sie benötigen, diese Mutexe, damit nicht mehrere threads können versuchen, ändern Sie die Daten in der gleichen Zeit (führt zu Korruption) oder die Daten in einem halb-Zustand geändert (führt zu ungültigen Daten).
Dein code würde wie folgt Aussehen:
Wenn Sie nicht mit dem Kakao (oder was kleines Cocoa-Programmierung habe ich mich von meinem kurzen Intermezzo mit einem iMac ist so schwach erinnern, dass es in der Nähe nutzlos ist), nutzen Sie einfach das Konzept, die übersetzungen in irgendeiner Sprache oder framework, das Sie haben:
Erklären, dass der Letzte Punkt etwas mehr: wenn Sie für die Synchronisation auf
self
für zwei völlig unabhängige Dinge (z.B. eine session-ID und eine Benutzer-ID), werden Sie sich gegenseitig blockieren trotz der Tatsache, dass es ist nicht notwendig, dies zu tun. Ich würde lieber zwei separate Mutexe zu halten, die Granularität gering.Natürlich, wenn Sie nur ein mutex auf die session-ID alleine (aber siehe unten für caveat), fühlen Sie sich frei zu verwenden
synchronized(self)
aber ich würde es vorziehen, es zu tun meinen Weg, so würde ich mich nicht erwischt, das hinzufügen eines weiteren geschützten Ressource später.In jedem Fall (das ist der Nachteil erwähnt), werden Sie wahrscheinlich feststellen, dass die Synchronisierung auf
self
würde nicht ausreichend schützen, eine statische variable, die würde geteilt auf mehrere Objekte. Die mutex sollte gehören zu den Daten statt, was ist die Verwendung es.self
für eine Instanz-Methode, die den Zugriff auf eine statische variable; vielleicht sync auf[self class]
oder auf ein Objekt, das in direktem Zusammenhang mit dem Wert, den Sie gerade Bearbeiten (z.B. wickeln Sie das int in ein NSNumber-und sync-auf der NSNumber).+initialize method
(siehe stackoverflow.com/questions/992070/...); aber einmal erstellt, geht es nicht Weg.[MyClass class]
, nicht[self class]
. Es scheint @JeremyP sagt[self class]
zurückkehren wird, ein anderes Objekt zu jeder Zeit, nicht um ein singleton.[self class]
gibt ein anderes Objekt jedes mal. Er sagt, dass, wenn Sie eine Unterklasse MySubclass, der erbt von MyClass,[self class]
zurück[MySubclass class]
aufgerufen, wenn eine Instanz vonMySubclass
. Es ist ein Gültiger Punkt.Ich denke, du bist besser dran mit Atomare Operationen zu ändern
session_id
. Ein Vorherige Frage Gespräche über Atomare Inkrement/Dekrement-Operationen für OS X, und auf dieser Seite spricht über dieOSAtomic
header-Datei. Atomare Operationen auf ganze zahlen, etwas, das leicht die hardware-unterstützte, wird wohl wesentlich schneller als mit Verriegelung konstruiert.OSAtomicIncrement32
, die sicher sein wird und nicht alle der Aufwand von Kakao-oder POSIX-Synchronisationsfunktionen.Antwort 4 Jahre später jetzt in iOS8. :o)
Das beste für mich ist die Verwendung einer singleton-Klasse wie folgt :
(yourFile.h)
=====================================================
(yourFile.m)
Müssen Sie nur rufen Sie die Methode 'generateSessionId' für jede neue Id-Wert.
Die Verwendung dieser Klasse für die Generierung der session-Ids sollten weit genug, denke ich.
Hoffe, es wird helfen, die Leser von diesem post. :o)
BEARBEITEN
Wie bereits von einigen Lesern, die NSInteger 'Wert' ist nicht thread sicher Folgen diesem Weg, nur das singleton ist.
Erhalten Sie eine komplette thread-safe 'Wert' instance variable ändern Sie dessen Typ NSInteger in NSNumber (werden umgewandelt in 'int' mit entsprechenden Methoden) das ist vollständig thread-sichere laut apples Dokumentation.
Dies ist möglicherweise der einfachste und Schnellste Weg zu bekommen, was gewünscht ist.
Es gibt viele Optionen, einschließlich (von high-level auf low-level)
@synchronized
Objective-C RichtlinieNSLock
,pthread_mutex_lock
und Atomare Operationen.Lesen Sie die "Synchronisierung" der Threading Programming Guide für details.