290 votes

Question sémantique : Le getter synthétisé de la propriété respecte la convention de dénomination Cocoa pour le retour des objets "possédés".

J'utilise actuellement le SDK iOS 5 pour développer mon application. J'essaie de faire d'une NSString une propriété, puis de la synthétiser dans le fichier .m (j'ai déjà fait cela auparavant sans problème). 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 les objets 'possédés'."

Voici mon code : .h

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

.m

@synthesize newTitle;

Quelqu'un a-t-il une idée de la façon dont je peux régler ce problème ? Merci !

0 votes

J'avais une erreur très similaire "Property follows Cocoa naming conventions for returning 'owned' objects" La réponse de Bavarious ci-dessous semble également résoudre ce problème.

620voto

Bavarious Points 43993

Je pense que la version du compilateur que vous utilisez est la suivante les règles de gestion de la mémoire pour les propriétés déclarées, également - plus spécifiquement, pour les accesseurs des propriétés déclarées :

Vous prenez possession d'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'il est synthétisé, donne une méthode appelée -newTitle d'où l'avertissement/erreur. -newTitle est censé être une méthode getter pour le module newTitle cependant, les conventions d'appellation stipulent qu'une méthode dont le nom commence par new renvoie un objet qui appartient à l'appelant, ce qui n'est pas le cas des méthodes getter.

Vous pouvez résoudre ce problème en :

  1. Renommer cette propriété :

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

    @property (strong, nonatomic, getter=theNewTitle) NSString *newTitle;
  3. En conservant à la fois le nom de la propriété et celui du getter, et en indiquant au compilateur que, même si le nom du getter commence par new il appartient à la none par opposition à la famille de méthodes new famille de méthodes :

    #ifndef __has_attribute
    #define __has_attribute(x) 0  // Compatibility with non-clang compilers
    #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 la propriété et comme nom du récupérateur, en ayant une méthode appelée -newTitle qui ne renvoie pas un objet appartenant à l'appelant peut être source de confusion pour les autres personnes lisant votre code.


Pour mémoire, Apple a publié Transition vers les notes de version ARC dans lequel ils déclarent :

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

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


Edit 17 Jan 2015 : Je viens de remarquer livraison récente de Clang qui suggère l'option 3 ci-dessus (utiliser objc_method_family(none) ), incluant un correctif, pour le cas général où un nom de propriété correspond à l'un des préfixes spéciaux de la famille de méthodes. Xcode intégrera probablement cette modification à terme.

6 votes

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

8 votes

Merveilleuse réponse. J'ai fait précéder les variables du mot "nouveau".

0 votes

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

57voto

Jackson Points 6654

Noms d'objets inacceptables

  • nouveauBouton
  • copyLabel
  • allocTitle

Noms d'objets acceptables

  • neueButton
  • mCopyLabel
  • _allocTitle

arc #auto-synthétisé #xcode-4.6.1

** EDIT **

Apparemment, vous ne pouvez pas utiliser mutableCopy soit.

1 votes

J'ai également remarqué que la "copie" ne peut pas être utilisée à partir de maintenant.

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 par des tests, j'ai pu déterminer que les variables membres qui commencent par 'new' aggravent le compilateur.

10voto

sooop Points 66

ARC ne permet pas d'utiliser "New...." dans le nom de la propriété. Mais vous pouvez utiliser "newTitle" en modifiant le nom du getter.

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

6voto

aquraishi Points 41

Il ne semble pas que ce que Bavarious suggérait soit ce que vous vouliez faire. Tout ce que vous voulez faire, c'est déclarer une variable d'instance NewTitle et ensuite synthétiser la propriété. Auparavant, nous devions déclarer la variable d'instance et la propriété. Plus maintenant.

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

.h

@interface ViewController : UIViewController

@property (nonatomic, strong) NSString *newTitle;

.m

@synthesize newTitle = _newTitle; // Use instance variable _newTitle for storage

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

Véase Exemple : Déclarer des propriétés et synthétiser 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 vous ayez résolu le problème. Pour Xcode 9, c'est une erreur, pas un avertissement. NS_RETURNS_NOT_RETAINED est ce dont vous avez 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