Domanda

Ho un app (utilizzando mantenere / release, non GC) che mantiene una variabile di istanza NSArray, che è esposto come una proprietà in questo modo:

@interface MyObject : NSObject
{
    NSArray* myArray;
}
@property (copy) NSArray* myArray;
@end

voglio accedere al contenuto di questa matrice da un thread secondario, che si stacca utilizzando -performSelectorInBackground:withObject:. È possibile e anzi probabile che l'array cambierà durante l'esecuzione del thread secondario.

Nel thread secondario che voglio fare qualcosa di simile:

if([self.myArray containsObject:foo])
{
    //do stuff
}

Dalla lettura della documentazione di filettatura, sembra che io dovrei essere in grado di utilizzare la direttiva @synchronized nelle funzioni di accesso in questo modo:

@implementation MyObject
- (NSArray *)myArray
{
    NSArray *result;
    @synchronized(self)
    {
        result = [myArray retain];
    }
    return [result autorelease];
}

- (void)setMyArray:(NSArray *)aMyArray
{
    @synchronized(self)
    {
        [myArray release];
        myArray = [aMyArray copy];
    }
}
@end

E 'questo tutto quello che devo fare per garantire la sicurezza dei thread, o è più complessa?

Aggiornamento: che ho successivamente trovato un grande articolo sul sito di Apple che risolve questo problema in modo approfondito: http://developer.apple.com/mac/library/technotes/tn2002/tn2059.html

È stato utile?

Soluzione

Il codice di cui sopra ti protegge dalla creazione della matrice in concomitanza, o di ottenere la matrice, mentre un altro è l'impostazione di esso. Poiché è una matrice non mutabile, questo protegge la matrice stessa bene.

Tuttavia, se per "la matrice cambierà" intendi sarete modificando gli elementi all'interno della matrice, si potrebbe ancora avere qualche problema. Ad esempio, se la matrice è stato riempito con NSMutableStrings, e si ha un filo che correva:

NSMutableString *foo = [myObject.myArray objectAtIndex:0];
[foo appendString:@"foo"];

e un altro che correva

NSMutableString *bar = [myObject.myArray objectAtIndex:0];
[bar appendString:@"bar"];

L'accesso alla matrice sarebbe sicuro (un thread dovrebbe aspettare l'altro per accedervi), tuttavia, l'accesso al puntatore foo / bar (che è lo stesso) non sarebbe, dato che le chiamate per ' appendString' sono al di fuori del blocco @synchronized.

Se questo è come l'array cambierà, sarà necessario sincronizzare questi punti di accesso pure. Sia con blocchi @synchronized più, o altri tipi di serrature. Vedere Uso Serrature

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top