A sintaxe e a semântica já estão bem definidas por outras excelentes respostas a essa pergunta. Como a execução e o desempenho não são bem detalhados, adicionarei minha resposta.
Qual é a diferença funcional entre esses 3?
Eu sempre considerei atômica um padrão bastante curioso. No nível de abstração em que trabalhamos, o uso de propriedades atômicas para uma classe como veículo para atingir 100% de segurança é um caso de esquina. Para programas multithread verdadeiramente corretos, a intervenção do programador é quase certamente um requisito. Enquanto isso, as características de desempenho e a execução ainda não foram detalhadas em profundidade. Tendo escrito alguns programas altamente multithread ao longo dos anos, eu estava declarando minhas propriedades nonatomic
o tempo todo porque o atômico não era sensível a nenhum propósito. Durante a discussão dos detalhes das propriedades atômicas e não atômicas, nesta pergunta , fiz alguns perfis e encontrei alguns resultados curiosos.
Execução
Está bem. A primeira coisa que gostaria de esclarecer é que a implementação de bloqueio é definida e abstraída. Louis usa @synchronized(self)
em seu exemplo - eu vi isso como uma fonte comum de confusão. A implementação não é realmente usada @synchronized(self)
; ele usa bloqueios de rotação no nível do objeto . A ilustração de Louis é boa para uma ilustração de alto nível usando construções com as quais todos estamos familiarizados, mas é importante saber que ela não é usada @synchronized(self)
.
Outra diferença é que as propriedades atômicas reterão / liberarão o ciclo de seus objetos no getter.
atuação
Aqui está a parte interessante: O desempenho usando acessos de propriedades atômicas em casos não contestados (por exemplo, thread único) pode ser realmente muito rápido em alguns casos. Em casos abaixo do ideal, o uso de acessos atômicos pode custar mais de 20 vezes a sobrecarga de nonatomic
. Enquanto o caso contestado usando 7 threads foi 44 vezes mais lento para a estrutura de três bytes (2,2 GHz Core i7 Quad Core, x86_64). A estrutura de três bytes é um exemplo de uma propriedade muito lenta.
Nota lateral interessante: os acessadores definidos pelo usuário da estrutura de três bytes foram 52 vezes mais rápidos que os acessadores atômicos sintetizados; ou 84% da velocidade dos acessadores não atômicos sintetizados.
Objetos em casos contestados também podem exceder 50 vezes.
Devido ao número de otimizações e variações nas implementações, é bastante difícil medir os impactos do mundo real nesses contextos. Você pode ouvir algo como "Confie, a menos que você crie um perfil e ache que é um problema". Devido ao nível de abstração, é realmente muito difícil medir o impacto real. A coleta de custos reais de perfis pode consumir muito tempo e, devido a abstrações, ser bastante imprecisa. Além disso, ARC vs MRC pode fazer uma grande diferença.
Então, vamos voltar atrás, sem focar na implementação de acessos a propriedades, incluiremos os suspeitos do costume objc_msgSend
e examinaremos alguns resultados de alto nível do mundo real para muitas chamadas para um NSString
getter em casos não contestados (valores em segundos):
- MRC não atômico getters implementados manualmente: 2
- MRC não atômico getter sintetizado: 7
- MRC atômico | getter sintetizado: 47
- ARC não atômico getter sintetizado: 38 (nota: o ARC está adicionando um número de ref de ciclo aqui)
- ARC atômico | getter sintetizado: 47
Como você provavelmente já adivinhou, a atividade de contagem de referência / ciclismo é um colaborador significativo dos atômicos e do ARC. Você também veria diferenças maiores nos casos contestados.
Embora eu preste muita atenção ao desempenho, ainda digo Semantics First! . Enquanto isso, o desempenho é uma baixa prioridade para muitos projetos. No entanto, conhecer os detalhes da execução e os custos das tecnologias usadas certamente não prejudica. Você deve usar a tecnologia certa para suas necessidades, propósitos e habilidades. Espero que isso poupe algumas horas de comparações e ajude você a tomar uma decisão melhor informada ao criar seus programas.