IOS switch-case Statement requires expression of integer type ('NSString *__strong' invalid)

2296 ワード

1.switchパラメータタイプ
switchパラメータタイプはinteger typeであることが要求され、正確にはintegerに変換できるタイプであり、これにはすべてのC基本データタイプ(signed/unsigned)char、(short/long signed/unsigned)int、float、double、longlong、bool(C++/objective-c))が含まれ、列挙タイプも含まれるが、文字列、構造体、連合体、オブジェクト、関数ポインタなどの複雑なタイプ.
文字列アドレスポインタ、オブジェクトアドレスポインタなどのポインタは、メモリ内のアドレスがunsigned intと理解できるため、UIntegerに変換できますが、なぜswitchのパラメータとして使用できないのでしょうか.これは、これらのポインタが動的に指定されているため、コンパイラ/プログラムを実行するたびに指定されたアドレスが異なるため、case文はどの条件が成立しているのか判断できず、caseの後の条件要求は定数でなければならない.複雑なオブジェクトの参照は往々にしてポインタを用いる指向され、ポインタがその値を確定できない以上、複雑なオブジェクトは自然にswitchパラメータとして機能しない.
e.g.1次のコードはNSStringポインタをswitchパラメータとして使用します.コンパイルに失敗しました.Statement requires expression of integer type('NSString*_strong'invalid)エラーをプロンプトします.
NSLog(@"(NSInteger)str=%lx", (NSInteger)str);
switch (str) {
case (NSInteger)nil:
NSLog(@"case nil");
break;

default:
NSLog(@"case default");
break;
}

e.g.2 switchパラメータ(NSString*)strを(UInteger)strに変更してコンパイルし、実行してもエラーはありませんが、case文は実行されません
NSLog(@"(NSInteger)str=%lx", (NSInteger)str);
switch ((NSInteger)str) {
case (NSInteger)nil:
NSLog(@"case nil");
break;

default:
NSLog(@"case default");
break;
}

再実行では,2回の実行(NSInteger)str出力のアドレス結果が異なることが分かった.
第1回ログ出力
(NSInteger)str=1001002e0
第2回ログ出力
(NSInteger)str=1002021c0
これにより、正確に決定されたcase文は自然に一致しません.マッチしたいならどうしますか?if-else文に変更するしかなく、より柔軟な効果が得られます.
NSString *str = [NSString stringWithFormat:@"I am a string."];
NSString *str2 = str;
if (str2 == str) {
NSLog(@"
str2 == str"); }else{ NSLog(@"
str2 != str"); }

ログ出力
str2 == str
2.case文ブロック注意問題
case文は、switchのパラメータの値を一致させるため、条件値は定数(const)でなければならない.caseはローカル文ブロックとして、独自の変数とメモリ空間を持つことができるので、case文ブロックの内部で変数を宣言するときは、ブロック内で定義された変数がブロック外で使用されないことを確保しなければならない.それ以外の場合、コンパイルエラーが発生します(ブロック外では変数に対して可視性がありません).間接的に使用する場合、実行エラーが発生する可能性があります(メモリアドレスが解放され、参照がエラーの位置を指す可能性があります.つまり、いわゆる野ポインタです).新しい変数が定義されている場合は、符号'{}'で囲まれる必要があります.そうしないと、コンパイルフェーズでエラーが発生する可能性があります.
case 1:{
int a=1;
NSLog(@"1\. a=%d", a);
}
NSLog(@"2\. a=%d", a); //             ‘a‘
int a=2; //      
NSLog(@"3\. a=%d", a);
break;

case 2:
int a=3; //           
break;
}