使用常量NSString作为NSUserDefaults的键

时间:2022-08-24 16:24:22

I'm using NSUSerDefaults to store user preferences. I remember reading somewhere that setting the keys as constants is a good idea - and I agree. The following code is what I currently have:

我使用NSUSerDefaults来存储用户偏好。我记得在某个地方读到过,把钥匙当作常数是一个好主意——我同意。以下代码是我目前的代码:

[[NSUserDefaults standardUserDefaults]
        setObject:[NSNumber numberWithInt:polygon.numberOfSides] 
           forKey:@"polygonNumberOfSides"];

I tried changing this to:

我试着把它改成:

@implementation Controller

NSString const *kPolygonNumberOfSides = @"polygonNumberOfSides";

-(void)savePolygonInfo {
    [[NSUserDefaults standardUserDefaults]
            setObject:[NSNumber numberWithInt:polygon.numberOfSides] 
               forKey:kPolygonNumberOfSides];
}

While this does work, it produces "warning: passing argument 1 of 'objectForKey:' discards qualifiers from pointer target type". I'm keen to keep my code free from compiler warnings. How can I fix this warning?

虽然这样做是有效的,但是它会产生“警告:传递‘objectForKey:’从指针目标类型中丢弃限定符”的参数1。我希望我的代码不受编译器警告的影响。我该如何修正这个警告?

5 个解决方案

#1


197  

You should use:

你应该使用:

NSString * const kPolygonNumberOfSides = @"..."; // const pointer

instead of:

而不是:

NSString const * kPolygonNumberOfSides = @"..."; // pointer to const

The first is a constant pointer to an NSString object, while the second is a pointer to a constant NSString object.

第一个是指向NSString对象的常量指针,第二个是指向常量NSString对象的指针。

It is a subtle difference. The compiler warning happens because setObject:forKey: is declared as follows:

这是一个微妙的区别。由于setObject:forKey:被声明为:

- (void)setObject:(id)value forKey:(NSString *)defaultName;

It is expecting the defaultName argument to be of type NSString *. When you instead pass in a pointer to a constant, you've given it something different.

它期望defaultName参数是NSString *类型。当你输入一个指向常数的指针时,你给了它不同的东西。

Update: I want to point out that these constants should be defined as static if they are only going to be used from within a single file. I say this because I have run across this problem myself: if you do not declare them as static, then they will exist in the global namespace, and you will not be able to use a variable with the same the same name in another file. see Constants in Objective-C for more information. To explain by example, this is what I currently use for keys that I only need to use in one .m file:

更新:我想指出的是,如果这些常量只在一个文件中使用,那么它们应该被定义为静态的。我之所以这么说,是因为我自己也遇到过这个问题:如果您不将它们声明为静态的,那么它们将存在于全局名称空间中,并且您将无法在另一个文件中使用与相同名称相同的变量。有关更多信息,请参见Objective-C中的常量。为了举例说明,这是我目前使用的键,我只需要在一个。m文件中使用:

static NSString * const kSomeLabel = @"...";

#2


28  

Don't use const with Objective-C objects, they weren't really designed to use it. NSString objects (among many others) are already immutable by default by virtue of their design, so making them const is useless.

不要对Objective-C对象使用const,它们并不是专门用来使用的。NSString对象(以及其他许多对象)由于其设计而在默认情况下已经是不可变的,因此使它们const是无用的。

As e.James suggested, you can use an NSString * const, which is a constant pointer to an NSString. This is subtly different from a const NSString * (equivalent to NSString const *), which is a pointer to a constant NSString. Using a NSString * const prevents you from reassigning kPoly to point to a new NSString object.

e。James建议,可以使用NSString * const,它是指向NSString的常量指针。这与const NSString *(相当于NSString const *)稍有不同,const NSString *是指向常量NSString的指针。使用NSString * const可以防止重新分配kPoly来指向一个新的NSString对象。

#3


14  

For access from other classes:

用于从其他类访问:

.h

. h

extern NSString * const PolygonNumberOfSidesPrefsKey;

.m

00

NSString * const PolygonNumberOfSidesPrefsKey = @"PolygonNumberOfSidesPrefsKey"

For access only inside current class:

只供当前类内的访问:

.m

00

static NSString * const kPolygonNumberOfSidesPrefsKey = @"PolygonNumberOfSidesPrefsKey"

#4


5  

I would suggest even making the constant more descriptive. A constant for the number of sides of a polygon could come from anywhere. As a suggestion, how about:

我甚至建议把这个常数变得更具描述性。一个多边形边数的常数可以来自任何地方。建议如下:

kDefaultsPolygonNumberOfSides;

instead.

代替。

#5


3  

For additional background about this issue, there is an excellent article on Wikipedia explaining the constant syntax with pointers: http://en.wikipedia.org/wiki/Const_correctness#Pointers_and_references

关于这个问题的其他背景知识,有一篇关于Wikipedia的优秀文章,用指针解释常量语法:http://en.wikipedia.org/wiki/const_correct #Pointers_and_references

#1


197  

You should use:

你应该使用:

NSString * const kPolygonNumberOfSides = @"..."; // const pointer

instead of:

而不是:

NSString const * kPolygonNumberOfSides = @"..."; // pointer to const

The first is a constant pointer to an NSString object, while the second is a pointer to a constant NSString object.

第一个是指向NSString对象的常量指针,第二个是指向常量NSString对象的指针。

It is a subtle difference. The compiler warning happens because setObject:forKey: is declared as follows:

这是一个微妙的区别。由于setObject:forKey:被声明为:

- (void)setObject:(id)value forKey:(NSString *)defaultName;

It is expecting the defaultName argument to be of type NSString *. When you instead pass in a pointer to a constant, you've given it something different.

它期望defaultName参数是NSString *类型。当你输入一个指向常数的指针时,你给了它不同的东西。

Update: I want to point out that these constants should be defined as static if they are only going to be used from within a single file. I say this because I have run across this problem myself: if you do not declare them as static, then they will exist in the global namespace, and you will not be able to use a variable with the same the same name in another file. see Constants in Objective-C for more information. To explain by example, this is what I currently use for keys that I only need to use in one .m file:

更新:我想指出的是,如果这些常量只在一个文件中使用,那么它们应该被定义为静态的。我之所以这么说,是因为我自己也遇到过这个问题:如果您不将它们声明为静态的,那么它们将存在于全局名称空间中,并且您将无法在另一个文件中使用与相同名称相同的变量。有关更多信息,请参见Objective-C中的常量。为了举例说明,这是我目前使用的键,我只需要在一个。m文件中使用:

static NSString * const kSomeLabel = @"...";

#2


28  

Don't use const with Objective-C objects, they weren't really designed to use it. NSString objects (among many others) are already immutable by default by virtue of their design, so making them const is useless.

不要对Objective-C对象使用const,它们并不是专门用来使用的。NSString对象(以及其他许多对象)由于其设计而在默认情况下已经是不可变的,因此使它们const是无用的。

As e.James suggested, you can use an NSString * const, which is a constant pointer to an NSString. This is subtly different from a const NSString * (equivalent to NSString const *), which is a pointer to a constant NSString. Using a NSString * const prevents you from reassigning kPoly to point to a new NSString object.

e。James建议,可以使用NSString * const,它是指向NSString的常量指针。这与const NSString *(相当于NSString const *)稍有不同,const NSString *是指向常量NSString的指针。使用NSString * const可以防止重新分配kPoly来指向一个新的NSString对象。

#3


14  

For access from other classes:

用于从其他类访问:

.h

. h

extern NSString * const PolygonNumberOfSidesPrefsKey;

.m

00

NSString * const PolygonNumberOfSidesPrefsKey = @"PolygonNumberOfSidesPrefsKey"

For access only inside current class:

只供当前类内的访问:

.m

00

static NSString * const kPolygonNumberOfSidesPrefsKey = @"PolygonNumberOfSidesPrefsKey"

#4


5  

I would suggest even making the constant more descriptive. A constant for the number of sides of a polygon could come from anywhere. As a suggestion, how about:

我甚至建议把这个常数变得更具描述性。一个多边形边数的常数可以来自任何地方。建议如下:

kDefaultsPolygonNumberOfSides;

instead.

代替。

#5


3  

For additional background about this issue, there is an excellent article on Wikipedia explaining the constant syntax with pointers: http://en.wikipedia.org/wiki/Const_correctness#Pointers_and_references

关于这个问题的其他背景知识,有一篇关于Wikipedia的优秀文章,用指针解释常量语法:http://en.wikipedia.org/wiki/const_correct #Pointers_and_references