Pergunta

Eu tenho um aplicativo (usando reter/liberação, não gc) que mantém um NSArray Variável de instância, que é exposta como uma propriedade como sim:

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

Quero acessar o conteúdo desta matriz de um fio secundário, que é destacado usando -performSelectorInBackground:withObject:. É possível e realmente provável que a matriz mude durante a execução do segmento secundário.

No tópico secundário, quero fazer algo assim:

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

Ao ler a documentação do encadeamento, parece que eu deveria poder usar o @synchronized Diretiva nos acessores como assim:

@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

É tudo o que preciso fazer para garantir a segurança do thread ou é mais complexo?

Atualizar: Posteriormente, encontrei um ótimo artigo no site da Apple que aborda esse problema em profundidade: http://developer.apple.com/mac/library/technotes/tn2002/tn2059.html

Foi útil?

Solução

Seu código acima o protege de definir a matriz simultaneamente ou obter a matriz enquanto outro está configurando -o. Como é uma matriz não mutável, isso protege a matriz em si muito bem.

No entanto, se "a matriz mudar", você quer querer editar os itens dentro da matriz, ainda poderá ter alguns problemas. Por exemplo, se a matriz foi preenchida com NSMutablestrings, e você teve um tópico que corria:

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

e outro que correu

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

O acesso à matriz seria seguro (um tópico teria que esperar o outro para acessá -lo), no entanto, o acesso ao ponteiro Foo/Bar (que é o mesmo) não seria, uma vez que ambas as chamadas para 'AppendString' são Fora do bloco @Synchronized.

Se é assim que sua matriz mudará, você precisará sincronizar esses pontos de acesso também. Com mais blocos @Synchronized ou outros tipos de bloqueios. Ver Usando bloqueios

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top