web-dev-qa-db-fra.com

erreur: la propriété atomique en écriture ne peut pas coupler un setter/getter synthétisé avec un setter/getter défini par l'utilisateur

J'ai récemment essayé de compiler un projet Xcode plus ancien (qui compilait bien auparavant), et maintenant je vois beaucoup d'erreurs de ce type:

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

Le modèle de code à l'origine de ces erreurs a toujours l'aspect suivant:

// Interface:

@property (retain) NSObject * someProperty;

// Implementation:

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

Je peux voir pourquoi l'erreur est générée. Je dis au compilateur de synthétiser mes accesseurs de propriété (à la fois getter et setter), puis immédiatement après, je remplace manuellement le setter. Ce code a toujours senti une petite odeur.

Alors, quelle est la bonne façon de faire cela? Si j'utilise @dynamic au lieu de @synthesize, je devrai également écrire le getter. Est-ce le seul moyen?

124
e.James

J'ai eu le même problème et après avoir fait quelques recherches, voici ma conclusion à ce sujet:

Le compilateur vous met en garde contre un @property que vous avez déclaré comme étant atomique (en omettant le mot clé nonatomic), mais vous fournissez une implémentation incomplète de la synchronisation de l'accès à cette propriété. 

Pour faire disparaître cet avertissement:

Si vous déclarez qu'un @property est atomique, effectuez l'une des opérations suivantes:

  • utilisez @dynamic ou;
  • utilisez @synthesize et conservez le setter et le getter synthétisés ou;
  • fournit une implémentation manuelle de both du passeur et du getter (sans utiliser l'une des directives ci-dessus).

Si vous déclarez le @property avec (nonatomic), vous pouvez combiner des implémentations manuelles et synthétisées de getters et de setters.

Mise à jour: Une note sur la synthèse automatique de propriétés

À partir de LLVM 4.0, CLang fournit une synthèse automatique des propriétés déclarées qui ne sont pas @dynamic. Par défaut, même si vous omettez le @synthesize, le compilateur vous fournira des méthodes d’acquisition et de définition. Cependant, la règle pour les propriétés atomiques reste la même: soit laisser le compilateur fournir les deux le getter et le séparateur, OR les implémenter vous-même les deux!

216
octy

Vous devez également implémenter le getter. Exemple:

// 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;
}
13
arturgrigor

Cette question, parmi les autres grands succès de la recherche sur "Propriété personnalisée Objective C", ne contient pas d'informations sur "setter =" ou "getter =".

Donc, pour fournir plus d'informations sur cette question:

Vous pouvez fournir l’appel @property avec votre propre méthode en écrivant

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

Notez les deux points pour la méthode de définition fournie.

Référence Documentation Apple

EDIT: Je ne sais pas trop comment les nouveaux changements apportés aux propriétés d'Objective-C (ils sont beaucoup plus intelligents maintenant) modifient les réponses à cette question. Peut-être que tout devrait être marqué comme obsolète.

12
Matias Forbord

Pour les autres personnes qui obtiennent cette erreur, pas pour la raison décrite par OP, vous avez probablement le même problème que moi:

Vous avez une propriété @ avec le même nom qu'une méthode - ().

Quelque chose comme ça:

@property UIView *mainView;

-(UIView *)mainView;
0
Albert Renshaw