Использование константы NSString в качестве ключа для NSUserDefaults - PullRequest
85 голосов
/ 16 апреля 2009

Я использую NSUSerDefaults для хранения пользовательских настроек. Я помню, как читал где-то, что установка ключей в качестве констант - хорошая идея - и я согласен. Следующий код - это то, что у меня сейчас есть:

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

Я попытался изменить это на:

@implementation Controller

NSString const *kPolygonNumberOfSides = @"polygonNumberOfSides";

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

Пока это работает, выдает "warning: passing argument 1 of 'objectForKey:' discards qualifiers from pointer target type". Я хочу, чтобы мой код был свободен от предупреждений компилятора. Как я могу исправить это предупреждение?

Ответы [ 5 ]

205 голосов
/ 16 апреля 2009

Вы должны использовать:

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

вместо:

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

Первый - это постоянный указатель на объект NSString, а второй - это указатель на постоянный объект NSString.

Это тонкая разница. Предупреждение компилятора происходит потому, что setObject:forKey: объявлено следующим образом:

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

Ожидается, что аргумент defaultName будет иметь тип NSString *. Когда вы вместо этого передаете указатель на константу, вы даете ей что-то другое.

Обновление: Я хочу отметить, что эти константы должны быть определены как static, если они будут использоваться только из одного файла. Я говорю это потому, что сам столкнулся с этой проблемой: если вы не объявите их как статические, они будут существовать в глобальном пространстве имен, и вы не сможете использовать переменную с таким же именем в другом файле. см. Константы в Objective-C для получения дополнительной информации. Для пояснения на примере это то, что я сейчас использую для ключей, которые мне нужно использовать только в одном .m файле:

static NSString * const kSomeLabel = @"...";
30 голосов
/ 16 апреля 2009

Не используйте const с объектами Objective-C, они не были предназначены для его использования. NSString объекты (среди многих других) уже неизменны по умолчанию в силу своего дизайна, поэтому их создание const бесполезно.

Как и e.James предложил , вы можете использовать NSString * const, который является постоянным указателем на NSString. Это немного отличается от const NSString * (эквивалент NSString const *), который является указателем на константу NSString. Использование NSString * const не позволяет переназначить kPoly для указания на новый объект NSString.

15 голосов
/ 11 ноября 2013

Для доступа из других классов:

.h

extern NSString * const PolygonNumberOfSidesPrefsKey;

.m

NSString * const PolygonNumberOfSidesPrefsKey = @"PolygonNumberOfSidesPrefsKey"

Для доступа только внутри текущего класса:

.m

static NSString * const kPolygonNumberOfSidesPrefsKey = @"PolygonNumberOfSidesPrefsKey"
5 голосов
/ 18 апреля 2009

Я бы предложил даже сделать константу более описательной. Константа для числа сторон многоугольника может прийти откуда угодно. Как предложение, как насчет:

kDefaultsPolygonNumberOfSides;

вместо.

3 голосов
/ 16 апреля 2009

Дополнительную информацию об этой проблеме можно найти в Википедии, где объясняется постоянный синтаксис с указателями: http://en.wikipedia.org/wiki/Const_correctness#Pointers_and_references

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...