"Enviando 'const NSString *' al parámetro de tipo 'NSString *' descarta los calificadores" advertencia

353

Tengo Constantes NSString, que quiero llamar como:

[newString isEqualToString:CONSTANT_STRING];

¿Algún código incorrecto aquí?

Recibí esta advertencia:

enviar 'const NSString *' al parámetro de tipo 'NSString *' descarta los calificadores

¿Cómo deben declararse?

user4951
fuente
2
¿Cómo se definen estas cadenas?

Respuestas:

917

Debe declarar su cadena constante de la siguiente manera:

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

en vez de:

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

El primero es un puntero constante a un NSStringobjeto, mientras que el segundo es un puntero a un NSStringobjeto constante .

El uso de le NSString * constimpide reasignar kSomeConstantString para apuntar a un NSStringobjeto diferente .

El método isEqualToString:espera un argumento de tipo NSString *. Si pasa un puntero a una cadena constante ( const NSString *), está pasando algo diferente de lo esperado.

Además, los NSStringobjetos ya son inmutables, por lo que hacerlos no const NSStringtiene sentido.

albertamg
fuente
3
Dijiste que el primero es el puntero constante a un objeto NSString. Eso significa que el puntero es constante. Por lo tanto, no puedo reasignar eso a otro NSString.
user4951
8
¡Ojalá pudiera darte diez votos a favor! ¡Gracias por su respuesta comprensible y muy útil!
Constantino Tsarouhas
1
¿Cómo en la tierra NSString * const es un puntero constante a NSString? ¿Cuál es su generador de gramática libre de contexto?
user4951
3
@Jim, el problema es que no has aprendido C correctamente, no lo culpes a los demás. El constcalificativo se aplica al término de su izquierda, y se aplica al término de su derecho sólo si no hay nada en su lado izquierdo (por ejemplo, const char *y una char const *son punteros no const a const char, pero char *constes un puntero constante a Char no constante )
8
+1. Y +1000 para "Además, los objetos NSString ya son inmutables, por lo que hacerlos constar NSString no tiene sentido".
Madbreaks
6

solo para poner todo en un lugar que se encuentra en varias publicaciones en stackoverflow y funciona para mí, #define es malo porque no puede beneficiarse de los tipos de variables, básicamente el compilador reemplaza toda aparición cuando compila (importe Constants.h siempre que lo necesite):

//  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
congelación_
fuente