Em Objective-C, você tem uma distinção entre propriedades atômicas e não atômicas:
@property (nonatomic, strong) NSObject *nonatomicObject;
@property (atomic, strong) NSObject *atomicObject;
Do meu entendimento, você pode ler e escrever propriedades definidas como atômicas de vários segmentos com segurança, enquanto escrever e acessar propriedades não atômicas ou ivars de vários segmentos ao mesmo tempo pode resultar em comportamento indefinido, incluindo erros de acesso incorreto.
Portanto, se você tiver uma variável como esta no Swift:
var object: NSObject
Posso ler e escrever nesta variável em paralelo com segurança? (Sem considerar o significado real de fazer isso).
objective-c
swift
Lassej
fonte
fonte
@atomic
ou@nonatomic
. ou apenas atômico por padrão. (Swift está tão incompleto, não podemos dizer muito agora)atomic
geralmente não é considerado suficiente para interação thread-safe com uma propriedade, exceto para tipos de dados simples. Para objetos, geralmente sincroniza-se o acesso através de threads usando bloqueios (por exemplo,NSLock
ou@synchronized
) ou filas GCD (por exemplo, fila serial ou fila simultânea com padrão "leitor-gravador").atomic
não garante segurança de thread para objetos; e (b) se alguém usar corretamente uma das técnicas de sincronização acima mencionadas para garantir a segurança do thread (entre outras coisas, evitando leitura / gravação simultânea), a questão atômica é discutível. Mas ainda precisamos / queremos isso para tipos de dados simples, ondeatomic
tem valor real. Boa pergunta!Respostas:
É muito cedo para assumir, pois nenhuma documentação de baixo nível está disponível, mas você pode estudar desde a montagem. Hopper Disassembler é uma ótima ferramenta.
Usos
objc_storeStrong
eobjc_setProperty_atomic
para não atômico e atômico respectivamente, ondeusa
swift_retain
delibswift_stdlib_core
e, aparentemente, não tem segurança de thread embutida.Podemos especular que palavras-chave adicionais (semelhantes a
@lazy
) podem ser introduzidas mais tarde.Atualização em 20/07/15 : de acordo com esta postagem do blog sobre singletons, o ambiente rápido pode tornar o thread de certos casos seguros para você, por exemplo:
Atualização 25/05/16 : fique de olho na proposta de evolução rápida https://github.com/apple/swift-evolution/blob/master/proposals/0030-property-behavior-decls.md - parece que é vai ser possível ter o
@atomic
comportamento implementado por você mesmo.fonte
O Swift não possui construções de linguagem em torno da segurança do thread. Presume-se que você usará as bibliotecas fornecidas para fazer seu próprio gerenciamento de segurança de thread. Há um grande número de opções que você tem na implementação de segurança de thread, incluindo pthread mutexes, NSLock e dispatch_sync como um mecanismo mutex. Veja a postagem recente de Mike Ash sobre o assunto: https://mikeash.com/pyblog/friday-qa-2015-02-06-locks-thread-safety-and-swift.html Portanto, a resposta direta à sua pergunta "Pode Leio e escrevo nesta variável em paralelo com segurança? " é não.
fonte
Provavelmente é muito cedo para responder a essa pergunta. Atualmente o swift não tem modificadores de acesso, então não há uma maneira óbvia de adicionar código que gerencia a simultaneidade em torno de um getter / setter de propriedades. Além disso, a linguagem Swift não parece ter nenhuma informação sobre concorrência ainda! (Ele também não tem KVO etc ...)
Acho que a resposta a essa pergunta ficará clara em versões futuras.
fonte
willSet
,didSet
- parece ser o primeiro passo no caminhoDetalhes
Links
Tipos implementados
Ideia principal
Amostra de acesso atômico
Uso
Resultado
fonte
Atomic
classe e execute-a usandoAtomic().semaphoreSample()
A partir do Swift 5.1, você pode usar wrappers de propriedade para criar uma lógica específica para suas propriedades. Esta é uma implementação de wrapper atômico:
Como usar:
fonte
Aqui está o wrapper de propriedade atômica que uso extensivamente. Fiz o mecanismo de bloqueio real um protocolo, para que eu pudesse experimentar com diferentes mecanismos. Tentei semáforos
DispatchQueues
e opthread_rwlock_t
. Opthread_rwlock_t
foi escolhido porque parece ter a sobrecarga mais baixa e uma chance menor de uma inversão de prioridade.fonte