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?
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:
@dynamic
ou;@synthesize
et conservez le setter et le getter synthétisés ou;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!
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;
}
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.
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;