2 Stimmen

Cocoa Threadsafe Mutable Collection Zugriff

Ich erstelle ein KVC/KVO-kompatibles veränderbares Array auf einem meiner Objekte auf die empfohlene Weise:

@interface Factory {
    NSMutableArray *widgets;
}
- (NSArray *)widgets;
- (void)insertObject:(id)obj inWidgetsAtIndex:(NSUInteger)idx;
- (void)removeObjectFromWidgetsAtIndex:(NSUInteger)idx;
@end

Es handelt sich hier eindeutig um ein heikles Problem der Thread-Sicherheit. In der insert y remove Methoden sperre ich den Array-Zugriff, um gleichzeitige Änderungen zu verhindern, da empfohlen .

Meine Frage ist, wie man die widgets accessor? Hier ist meine Implementierung:

- (NSArray *)widgets {
    [widgetLock lock];
    NSArray *a = [[widgets copy] autorelease];
    [widgetLock unlock];
    return a;
}

Ist es thread-sicher?

2voto

Alex Punkte 26769

Ihr widgets Accessor sollte in Ordnung sein, obwohl Sie sich bewusst sein sollten, dass keines der Objekte in diesem Array gesperrt ist. Sie könnten also Probleme bekommen, wenn Sie versuchen, gleichzeitig Code wie

[[[myFactory widgets] objectAtIndex:7] setName:@"mildred"];

et

[myTextField setStringValue:[[[myFactory widgets] objectAtIndex:7] name]]; // mildred? or something else?

Da die Objekte in Ihrem Array nicht gesperrt sind, könnten Sie in Race Conditions oder Leser/Schreiber-Typ Probleme laufen. Ist Multithreading nicht eine Freude?

Um die KVC-Konformität zu gewährleisten, empfehle ich die Implementierung von objectInWidgetsAtIndex: y countOfWidgets anstelle einer widgets Accessor. Denken Sie daran, dass KVC Beziehungen modelliert, nicht Array-Eigenschaften. Sie würden also etwas aufrufen wie [myFactory mutableArrayValueForKey:@"widgets"] um ein Array zu erhalten, das die widgets Eigentum.

2voto

Matt Gallagher Punkte 14710

Anstatt eine eigene Sperre zu erstellen, können Sie auch die in der Sprache integrierte Sperre verwenden:

d.h.

- (NSArray *)widgets {
    @synchronized(widgets)
    {
        NSArray *a = [[widgets copy] autorelease];
        return a;
    }
}

und verwenden Sie ähnliche Sperren in allen anderen Methoden, die auf widgets . (Der Parameter widgets hineingegangen @synchronized bezieht sich auf die Instanzvariable, nicht auf die Methode).

Die Bemerkung von Alex über den Zugang zu enthaltenen Objekten gilt nach wie vor.

0voto

tcurdt Punkte 12170

Sie benötigen eine Sperre für alle Lese- und Schreibmethoden. Wenn Ihre einfügen und entfernen auch sperren (wie Sie sagte) dann die Accessor-Methode sollte in Ordnung sein, wie das.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X