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?


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!


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;
}

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.


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;
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.