290 votes

Problème sémantique : Le getter synthétisé de la propriété suit la convention de dénomination Cocoa pour renvoyer des objets "appartenant"

Je suis actuellement en train d'utiliser la SDK iOS 5 pour développer mon application. Je cherche à faire d'une NSString une propriété, puis à la synthesizer dans le fichier .m (j'ai déjà fait cela sans problème auparavant). Maintenant, je suis tombé sur ceci : "Problème sémantique : Le getter synthétisé de la propriété suit la convention de nommage Cocoa pour retourner des objets 'owned'."

Voici mon code : .h

@interface ViewController : UIViewController {
     NSString *newTitle;
}
@property (strong, nonatomic) NSString *newTitle;

.m

@synthesize newTitle;

Est-ce que quelqu'un a une idée de comment je pourrais résoudre cela ? Merci !!

0 votes

J'ai eu une erreur très similaire "Property suit les conventions de nommage Cocoa pour retourner des objets 'owned'" La réponse de Bavarious ci-dessous semble également résoudre cela.

620voto

Bavarious Points 43993

Mon hypothèse est que la version du compilateur que vous utilisez suit les règles de gestion de la mémoire pour les propriétés déclarées, notamment pour les accesseurs des propriétés déclarées :

Vous possédez un objet si vous le créez en utilisant une méthode dont le nom commence par « alloc », « new », « copy » ou « mutableCopy ».

Une propriété nommée newTitle, lorsqu'elle est synthétisée, donne une méthode appelée -newTitle, d'où le avertissement/erreur. -newTitle est censée être une méthode d'obtention pour la propriété newTitle, cependant les conventions de nommage indiquent qu'une méthode dont le nom commence par new renvoie un objet possédé par l'appelant, ce qui n'est pas le cas des méthodes d'obtention.

Vous pouvez résoudre cela en :

  1. Renommant cette propriété :

    @property (strong, nonatomic) NSString *theNewTitle;
  2. Conserver le nom de propriété et spécifier un nom d'obtention qui ne commence pas par un des préfixes des noms de méthode spéciaux :

    @property (strong, nonatomic, getter=theNewTitle) NSString *newTitle;
  3. Conserver à la fois le nom de propriété et le nom de l'obtention, et dire au compilateur que, même si le nom de l'obtention commence par new, il appartient à la famille de méthodes none par opposition à la famille de méthodes new:

    #ifndef __has_attribute
    #define __has_attribute(x) 0  // Compatibilité avec les compilateurs non-Clang
    #endif
    
    #if __has_attribute(objc_method_family)
    #define BV_OBJC_METHOD_FAMILY_NONE __attribute__((objc_method_family(none)))
    #else
    #define BV_OBJC_METHOD_FAMILY_NONE
    #endif
    
    @interface ViewController : UIViewController
    @property (strong, nonatomic) NSString *newTitle;
    - (NSString *)newTitle BV_OBJC_METHOD_FAMILY_NONE;
    @end

    Notez que même si cette solution vous permet de garder newTitle à la fois comme nom de propriété et comme nom d'obtention, avoir une méthode appelée -newTitle qui ne retourne pas un objet possédé par l'appelant peut être déroutant pour d'autres personnes lisant votre code.


Pour information, Apple a publié des Notes de mise à jour sur la transition vers l'ARC dans lesquelles ils affirment :

Vous ne pouvez pas donner à une propriété un nom qui commence par new ou copy.

Ils ont déjà été informés que leur déclaration n'est pas tout à fait précise : le coupable est le nom de la méthode d'obtention, et non pas le nom de la propriété.


Édition du 17 janvier 2015 : Je viens de remarquer un commit récent à Clang qui suggère l'option 3 ci-dessus (utilisation de objc_method_family(none)), y compris une correction automatique, pour le cas général où un nom de propriété correspond à l'un des préfixes de la famille de méthodes spéciales. Xcode incorporera probablement ce changement à l'avenir.

6 votes

A fonctionné comme un charme mec!! Merci!!! Pour référence future - J'ai utilisé "@property (strong, nonatomic, getter=theNewTitle) NSString *newTitle;"

8 votes

Réponse merveilleuse. J'avais des variables préfixées "new."

0 votes

J'ai aussi ce problème, et ça me fait perdre beaucoup de temps! Tu es vraiment un génie Merci!

57voto

Jackson Points 6654

Noms d'objet inacceptables

  • newButton
  • copyLabel
  • allocTitle

Noms d'objet acceptables

  • neueButton
  • mCopyLabel
  • _allocTitle

arc #auto-synthesized #xcode-4.6.1

** MODIFICATION **

Apparemment, vous ne pouvez pas utiliser mutableCopy non plus.

1 votes

J'ai également remarqué que "copier" ne peut pas être utilisé pour le moment.

31voto

Michael Points 261

Le nom du membre commençant par new est ce qui déclenche l'avertissement. Changez le nom en editedTitle et l'avertissement disparaîtra. Je n'ai pas pu trouver de documentation confirmant cela mais grâce à des tests, j'ai pu déterminer que les variables membres commençant par 'new' aggravent le compilateur.

10voto

sooop Points 66

ARC ne permet pas d'utiliser "Nouveau...." dans le nom de la propriété. mais vous pouvez utiliser "newTitle" en changeant le nom du getter.

@property (nonatomic, strong, getter=theNewTitle) NSString *newTitle;

6voto

aquraishi Points 41

Il semble que ce que Bavarious suggérait n'était pas ce que vous vouliez faire. Tout ce que vous voulez faire, c'est déclarer une variable d'instance NewTitle puis synthétiser la propriété. Nous avions l'habitude de devoir déclarer la variable d'instance et la propriété. Plus maintenant.

Maintenant, je crois que la bonne façon de faire cela est la suivante :

.h

@interface ViewController : UIViewController

@property (nonatomic, strong) NSString *newTitle;

.m

@synthesize newTitle = _newTitle; // Utiliser la variable d'instance _newTitle pour le stockage

La variable d'instance pour la propriété newTitle est synthétisée. Vous ne voulez pas que votre variable d'instance soit la même que votre propriété - trop facile de faire des erreurs.

Voir Exemple : Déclaration des propriétés et synthèse des accesseurs

0 votes

Cela dépend de la version du compilateur. Les versions récentes de clang émettent un avertissement dans ce cas, c'est pourquoi j'ai mentionné la version du compilateur dans ma réponse.

0 votes

Je ne pense pas que tu aies résolu le problème. Pour Xcode 9, c'est une erreur, pas un avertissement. NS_RETURNS_NOT_RETAINED c'est ce dont tu as besoin.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X