Aviso “enviando 'const NSString *' para o parâmetro do tipo 'NSString *' descarta qualificadores”

353

Eu tenho constantes NSString, que eu quero chamar como:

[newString isEqualToString:CONSTANT_STRING];

Algum código errado aqui?

Eu recebi este aviso:

enviar 'const NSString *' para o parâmetro do tipo 'NSString *' descarta qualificadores

Como estes devem ser declarados?

user4951
fonte
2
como essas strings são definidas?

Respostas:

917

Você deve declarar sua cadeia constante da seguinte maneira:

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

ao invés de:

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

O primeiro é um ponteiro constante para um NSStringobjeto, enquanto o último é um ponteiro para um NSStringobjeto constante .

O uso de um NSString * constimpede que você reatribua o kSomeConstantString para apontar para um NSStringobjeto diferente .

O método isEqualToString:prevê um argumento do tipo NSString *. Se você passar um ponteiro para uma string constante ( const NSString *), estará passando algo diferente do que o esperado.

Além disso, os NSStringobjetos já são imutáveis, tornando-os const NSStringsem sentido.

albertamg
fonte
3
Você disse que o primeiro é o ponteiro constante para um objeto NSString. Então isso significa que o ponteiro é constante. Portanto, não posso reatribuir isso para outro NSString.
user4951
8
Eu gostaria de poder lhe dar dez votos positivos! Obrigado pela sua resposta compreensível e muito útil!
Constantino Tsarouhas
11
como na terra NSString * const é um ponteiro const para NSString? Qual é o seu gerador de gramática livre de contexto?
user4951
3
@ Jim, o problema está em você não ter aprendido C corretamente, não culpe os outros. O constqualificador aplica-se ao termo à esquerda e aplica-se ao termo à direita somente se não houver nada no lado esquerdo (por exemplo, const char *e a char const *são ponteiros não const para const char, mas char *consté um ponteiro const para char não const )
8
+1. E +1000 para "Além disso, os objetos NSString já são imutáveis, tornando-os constantes no NSString não faz sentido".
Madbreaks
6

apenas para colocar tudo em um único local encontrado em várias postagens no stackoverflow e funciona para mim, #define é ruim porque você não pode se beneficiar de tipos de variáveis, basicamente o compilador substitui toda a ocorrência quando compila (importe Constants.h sempre que precisar):

//  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
congelando_
fonte