web-dev-qa-db-ja.com

「タイプ 'NSString *'のパラメーターに 'const NSString *'を送信すると、修飾子が破棄されます」という警告

NSString定数があり、次のように呼び出します。

[newString isEqualToString:CONSTANT_STRING];

ここに間違ったコードがありますか?

私はこの警告を受けました:

「const NSString *」をタイプ「NSString *」のパラメータに送信すると、修飾子が破棄されます

これらはどのように宣言されるべきですか?

338
user4951

次のように定数文字列を宣言する必要があります。

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

の代わりに:

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

前者はNSStringオブジェクトへの定数ポインターであり、後者は定数NSStringオブジェクトへのポインターです。

NSString * constを使用すると、別のNSStringオブジェクトを指すようにkSomeConstantStringを再割り当てできなくなります。

メソッドisEqualToString:には、タイプNSString *の引数が必要です。定数文字列(const NSString *)にポインターを渡すと、予想とは異なる何かを渡します。

その上、NSStringオブジェクトはすでに不変なので、それらをconst NSStringにすることは無意味です。

889
albertamg

stackoverflowのさまざまな投稿で見つかった1つの場所にすべてを置くだけで、#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
6
freezing_

これを読むのに数分かかります。定数に関するポインター地獄の良い読みとその逆。

http://c-faq.com/decl/spiral.anderson.html

4
user3693546