Ostrzeżenie „wysyłanie„ const NSString * ”do parametru typu„ NSString * ”odrzuca kwalifikatory”

353

Mam stałe NSString, które chcę nazwać:

[newString isEqualToString:CONSTANT_STRING];

Masz tutaj zły kod?

Dostałem to ostrzeżenie:

wysyłanie „const NSString *” do parametru typu „NSString *” odrzuca kwalifikatory

Jak należy je zadeklarować?

użytkownik4951
źródło
2
jak zdefiniowane są te ciągi?

Odpowiedzi:

916

Powinieneś zadeklarować swój stały ciąg w następujący sposób:

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

zamiast:

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

Pierwszy z nich jest stałym wskaźnikiem do NSStringobiektu, podczas gdy drugi jest wskaźnikiem do stałego NSStringobiektu.

Użycie a NSString * constuniemożliwia ponowne przypisanie kSomeConstantString w celu wskazania innego NSStringobiektu.

Metoda isEqualToString:oczekuje argumentu typu NSString *. Jeśli przekażesz wskaźnik do stałego łańcucha ( const NSString *), przekażesz coś innego niż się spodziewa.

Poza tym NSStringobiekty są już niezmienne, więc ich tworzenie const NSStringjest bez znaczenia.

albertamg
źródło
3
Powiedziałeś, że ten pierwszy jest stałym wskaźnikiem do obiektu NSString. Oznacza to, że wskaźnik jest stały. Dlatego nie mogę ponownie przypisać tego do innego NSString.
user4951
8
Chciałbym dać ci dziesięć pozytywnych opinii! Dziękujemy za zrozumiałą i bardzo pomocną odpowiedź!
Constantino Tsarouhas
1
jak u licha NSString * const jest stałym wskaźnikiem do NSString? Jaki jest ich kontekstowy generator gramatyki?
user4951
3
@Jim problemem jest to, że nie nauczyłeś się poprawnie C, nie obwiniaj innych. constKwalifikator dotyczy terminu na jego lewej stronie, a to odnosi się do terminu na jej prawa tylko wtedy, gdy nie ma nic na jej lewej stronie (np const char *i char const *są non-const wskaźniki do const char, ale char *constjest wskaźnikiem const do const char ).
8
+1. I +1000 za „Poza tym obiekty NSString są już niezmienne, więc uczynienie ich stałymi NSString jest bez znaczenia”.
Madbreaks
6

po prostu umieszczam wszystko w jednym miejscu, które można znaleźć w różnych postach na przepełnieniu stosu i działa dla mnie, #define jest złe, ponieważ nie możesz korzystać z typów zmiennych, w zasadzie kompilator zastępuje wszystkie wystąpienia podczas kompilacji (importuj Constants.h, kiedy potrzebujesz):

//  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
zamrażanie_
źródło