error: a propriedade atômica gravável não pode emparelhar um setter / getter sintetizado com um setter / getter definido pelo usuário

128

Recentemente, tentei compilar um projeto antigo do Xcode (que costumava compilar muito bem) e agora estou vendo muitos erros deste formulário:

error: writable atomic property 'someProperty' cannot pair a synthesized setter/getter with a user defined setter/getter

O padrão de código que causa esses erros sempre se parece com isso:

// Interface:

@property (retain) NSObject * someProperty;

// Implementation:

@synthesize someProperty; // to provide the getter
- (void)setSomeProperty:(NSObject *)newValue
{
    //..
}

Eu posso ver por que o erro está sendo gerado. Eu digo ao compilador para sintetizar meus acessadores de propriedades (getter e setter) e, imediatamente depois, eu substituo o setter manualmente. Esse código sempre cheirava um pouco.

Então, qual é a maneira correta de fazer isso? Se eu usar em @dynamicvez de @synthesize, terei que escrever o getter também. Este é o único caminho?

e.James
fonte
Isso acontece apenas com atomicpropriedades? No caso de propriedades atômicas, pode ser uma boa idéia manter o par getter / setter sincronizado em relação à estratégia de bloqueio. Isso é difícil se uma parte é sintetizada enquanto a outra é um código personalizado.
Nikolai Ruhe
Certamente desaparece se eu tornar a propriedade não atômica. Interessante. Eu nem tinha pensado no problema de sincronização.
e.James
Visitei este tópico para encontrar uma solução para esse problema exato. Eu realmente não quero escrever um getter e um setter sozinho. Oh bem ...
Constantino Tsarouhas 13/08
Por padrão, todas as propriedades são atômicas e precisamos torná-las não atômicas explicitamente. As propriedades atômicas são seguras para threads, portanto, não podemos implementar setter e getter para elas, porque isso mudará sua funcionalidade de thread safe. Espero que você entenda o motivo do erro.
Mohd Haider 27/03

Respostas:

218

Eu tive o mesmo problema e depois de fazer um pouco de pesquisa, aqui está minha conclusão sobre esse problema:

O compilador avisa sobre um @propertyque você declarou como atômico (ou seja, omitindo a nonatomicpalavra - chave), mas você fornece uma implementação incompleta de como sincronizar o acesso a essa propriedade.

Para fazer esse aviso desaparecer:

Se você declarar @propertya como atômico, siga um destes procedimentos:

  • usar @dynamicou;
  • use @synthesizee mantenha o setter e getter sintetizado ou;
  • proporcionar uma aplicação manual , tanto da incubadora e o absorvente (sem o uso de uma das directivas acima).

Se você declarar @propertycom (nonatomic), poderá combinar implementações manuais e sintetizadas de getters e setters.

Atualização: uma observação sobre a síntese automática de propriedades

A partir do LLVM 4.0, o CLang fornece auto-síntese para propriedades declaradas que não são @dynamic. Por padrão, mesmo se você deixar de fora @synthesize, o compilador fornecerá métodos getter e setter para você. No entanto, a regra para propriedades atômicas ainda é o mesmo: Deixe o compilador fornecer tanto o getter e setter, ou implementar-los tanto a si mesmo!

octy
fonte
Obrigado! "declarar a propriedade @ com (não atômica)"
Nianliang 3/12/12
14

Você precisa implementar o getter também. Exemplo:

// Interface:

@property (retain) NSObject * someProperty;

// Implementation:

- (void)setSomeProperty:(NSObject *)newValue
{
    @synchronized (self)
    {
        // ...
    }
}

- (NSObject *)someProperty
{
    NSObject *ret = nil;

    @synchronized (self)
    {
        ret = [[someProperty retain] autorelease];
    }

    return ret;
}
arturgrigor
fonte
12

Esta pergunta, entre os outros principais hits que você obtém ao pesquisar "propriedade customizada do objetivo C", não é atualizada com informações sobre "setter =" ou "getter =".

Portanto, para fornecer mais informações sobre esta questão:

Você pode fornecer a chamada @property com seu próprio método escrevendo

    @property(setter = MySetterMethod:, getter = MyGetterMethod)

Observe os dois pontos do método de incubação fornecido.

Referência à documentação da Apple

EDIT: Não tenho muita certeza de como as novas alterações nas propriedades do Objective-C (agora são muito mais inteligentes) alteram as respostas a esta pergunta. Talvez tudo deva estar marcado como desatualizado.

Matias Forbord
fonte
Descobri que definir o método setter não removeu o aviso. por exemplo -> "@property (atribuir, setter = setDelegate :) id delegate;" Nesse caso, tudo o que posso fazer é adicionar meu próprio getter ou a propriedade não atômica, o que não tenho certeza se devo, já que estou configurando o delegado 'atomicamente', não importa ter a propriedade não atômica , ou pelo que entendi.
David van Dugteren
Interessante, David. Em que "versão" do Objective-C está (suponho que dizer que a versão XCode seria mais útil)? Não sei ao certo o que as alterações recentes no Objective-C, especificamente no iOS 6, afetam.
Matias Forbord 25/09/12
0

Para outras pessoas que estão recebendo esse erro não pelo motivo descrito pelo OP, você provavelmente tem o mesmo problema que eu:

Você tem uma propriedade @ com o mesmo nome que um método - ().

Algo assim:

@property UIView *mainView;

-(UIView *)mainView;
Albert Renshaw
fonte