J'utilise NSUSerDefaults pour stocker les préférences de l'utilisateur. Je me souviens avoir lu quelque part que définir les clés comme constantes est une bonne idée - et je suis d'accord. Le code suivant est ce que j'ai actuellement:
[[NSUserDefaults standardUserDefaults]
setObject:[NSNumber numberWithInt:polygon.numberOfSides]
forKey:@"polygonNumberOfSides"];
J'ai essayé de changer cela en:
@implementation Controller
NSString const *kPolygonNumberOfSides = @"polygonNumberOfSides";
-(void)savePolygonInfo {
[[NSUserDefaults standardUserDefaults]
setObject:[NSNumber numberWithInt:polygon.numberOfSides]
forKey:kPolygonNumberOfSides];
}
Bien que cela fonctionne, il produit "warning: passing argument 1 of 'objectForKey:' discards qualifiers from pointer target type
". Je tiens à garder mon code exempt d'avertissements du compilateur. Comment puis-je corriger cet avertissement?
Tu devrais utiliser:
NSString * const kPolygonNumberOfSides = @"..."; // const pointer
au lieu de:
NSString const * kPolygonNumberOfSides = @"..."; // pointer to const
Le premier est un pointeur constant vers un objet NSString, tandis que le second est un pointeur vers un objet NSString constant.
C'est une subtile différence. L'avertissement du compilateur se produit car setObject:forKey:
est déclaré comme suit:
- (void)setObject:(id)value forKey:(NSString *)defaultName;
Il s'attend à ce que l'argument defaultName
soit de type NSString *
. Lorsque vous passez plutôt un pointeur vers une constante, vous lui avez donné quelque chose de différent.
Mise à jour: Je tiens à souligner que ces constantes doivent être définies comme static
si elles le sont ne sera utilisé qu'à partir d'un seul fichier. Je dis cela parce que j'ai moi-même rencontré ce problème: si vous ne les déclarez pas statiques, ils existeront dans l'espace de noms global et vous ne pourrez pas utiliser une variable portant le même nom dans un autre fichier. voir Constantes dans Objective-C pour plus d'informations. Pour expliquer par exemple, c'est ce que j'utilise actuellement pour les clés que je n'ai besoin d'utiliser que dans un .m
fichier:
static NSString * const kSomeLabel = @"...";
N'utilisez pas const
avec des objets Objective-C, ils n'étaient pas vraiment conçus pour l'utiliser. NSString
les objets (parmi beaucoup d'autres) sont déjà immuables par défaut en raison de leur conception, donc les rendre const
est inutile.
Comme e.James l'a suggéré , vous pouvez utiliser un NSString * const
, qui est un pointeur constant vers un NSString
. Ceci est subtilement différent d'un const NSString *
(équivalent à NSString const *
), qui est un pointeur vers une constante NSString
. Utilisant un NSString * const
vous empêche de réaffecter kPoly
pour pointer vers un nouvel objet NSString
.
Pour l'accès à partir d'autres classes:
.h
extern NSString * const PolygonNumberOfSidesPrefsKey;
.m
NSString * const PolygonNumberOfSidesPrefsKey = @"PolygonNumberOfSidesPrefsKey"
Pour l'accès uniquement à l'intérieur de la classe actuelle:
.m
static NSString * const kPolygonNumberOfSidesPrefsKey = @"PolygonNumberOfSidesPrefsKey"
Je suggérerais même de rendre la constante plus descriptive. Une constante du nombre de côtés d'un polygone peut provenir de n'importe où. Comme suggestion, que diriez-vous:
kDefaultsPolygonNumberOfSides;
au lieu.
Pour plus d'informations sur ce problème, il existe un excellent article sur Wikipedia expliquant la syntaxe constante avec des pointeurs: http://en.wikipedia.org/wiki/Const_correctness#Pointers_and_references