Предупреждение «отправка const NSString *» параметру типа «NSString *» отменяет квалификаторы »

353

У меня есть константы NSString, которые я хочу назвать как:

[newString isEqualToString:CONSTANT_STRING];

Любой неправильный код здесь?

Я получил это предупреждение:

отправка 'const NSString *' в параметр типа 'NSString *' отбрасывает квалификаторы

Как они должны быть объявлены?

user4951
источник
2
как определяются эти строки?

Ответы:

917

Вы должны объявить вашу постоянную строку следующим образом:

NSString * const kSomeConstantString = @""; // constant pointer

вместо:

const NSString * kSomeConstantString = @""; // pointer to constant
// equivalent to
NSString const * kSomeConstantString = @"";

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

Использование a не NSString * constпозволяет переназначить kSomeConstantString для указания на другой NSStringобъект.

Метод isEqualToString:ожидает аргумент типа NSString *. Если вы передаете указатель на константу string ( const NSString *), вы передаете что-то отличное от ожидаемого.

Кроме того, NSStringобъекты уже неизменны, поэтому создавать их const NSStringбессмысленно.

albertamg
источник
3
Вы сказали, что первый является постоянным указателем на объект NSString. Это означает, что указатель является постоянным. Следовательно, я не могу переназначить это другому NSString.
user4951
8
Я хотел бы дать вам десять голосов! Спасибо за ваш понятный и очень полезный ответ!
Константино Царухас
1
как в земле NSString * const является указателем const на NSString? Каков их контекстный генератор грамматики?
user4951
3
@ Джим, проблема в том, что ты не выучил C должным образом, не вини в этом других. constКлассификатор относится к термину на его слева, и это относится к термину на его права , только если нет ничего на левой сторону (например , const char *и char const *являются неконстантными указателями на константный полукокс, но char *constуказатель сопзЬ к неконстантному полукоксу ).
8
+1. И +1000 за «Кроме того, объекты NSString уже неизменны, поэтому делать их постоянными NSString бессмысленно».
Madbreaks
6

просто поместить все в одно место, которое находится на разных постах в stackoverflow и работает для меня, #define плохо, потому что вы не можете извлечь выгоду из типов переменных, в основном компилятор заменяет все вхождения при компиляции (импортируйте Constants.h всякий раз, когда вам нужно):

//  Constants.h
#import <Foundation/Foundation.h>

@interface Constants : NSObject

extern NSString *APP_STATE_LOGGED_IN;
extern NSString *APP_STATE_LOGGED_OUT;
@end

// Constants.m
#import <Foundation/Foundation.h>
#import "Constants.h"

@implementation Constants

NSString *APP_STATE_LOGGED_IN  = @"APP_STATE_LOGGED_IN";
NSString *APP_STATE_LOGGED_OUT = @"APP_STATE_LOGGED_OUT";
@end
freezing_
источник