IOS switch-case知多少


1. switch參數類型

switch參數類型要求是integer type,准確來講,是可以轉換成integer的類型, 這包括所有的C基本數據類型((signed/unsigned)char, (short/long signed/unsigned)int, float, double, longlong, bool(C++/objective-c) ),還有枚舉類型,但是不包括字符串、結構體、聯合體、對象、函數指針等復雜類型。

其實字符串地址指針、對象址指指針等指針,都是可以轉化為UInteger, 因為它們在內存中地址都可以理解成unsigned int, 但是為什么不能使用這些指針作為switch的參數呢? 這是因為這些指針都是動態指定的,每次運行編譯器/程序指定的地址不盡相同,這就會導致case語句會無法判斷是哪一種條件成立,而case后面的條件要求必須是常量;復雜對象的引用往往是利用指針指向的,既然指針都是無法確定其值的,所以復雜對象自然無法作為switch參數了.

e.g. 1 下面這段代碼使用NSString指針作為switch參數,編譯無法通過, 提示Statement requires expression of integer type('NSString *__strong' invalid)錯誤

        NSString *str = [NSString stringWithFormat:@"I am a string."];
        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語句

        NSString *str = [NSString stringWithFormat:@"I am a string."];
        NSLog(@"(NSInteger)str=%lx", (NSInteger)str);
        switch ((NSInteger)str) {
            case (NSInteger)nil:
                NSLog(@"case nil");
                break;
                
            default:
                NSLog(@"case default");
                break;
        }

 再次運行發現,兩次運行(NSInteger)str 輸出的地址結果都不一樣

第1次 Log輸出

(NSInteger)str=1001002e0

 第2次 Log輸出

(NSInteger)str=1002021c0

 

這樣自然就匹配不到正確確定的case 語句了。如果想要匹配怎么辦?那就只能改用if-else語句了,能達到更靈活的效果。

        NSString *str = [NSString stringWithFormat:@"I am a string."];
        NSString *str2 = str;
        if (str2 == str) {
            NSLog(@"\nstr2 == str");
        }else{
             NSLog(@"\nstr2 != str");
        }

 Log輸出

str2 == str

 

2.case 語句塊注意問題

  • case 語句是為了匹配switch中的參數的值,所以其條件值必須是常數(const).
  • case 作為一個局部語句塊,也能擁有的自己的變量與內存空間,那么在case語句塊內部聲明變量時,應該確保塊內定義的變量,不被塊外使用,否則會導致編譯錯誤(塊外對變量不具有可見性);如果是間接使用,則可能導致運行錯誤(內存地址已被釋放,在引用可能指向一個錯誤位置, 也就是所謂的野指針)。
  • 如果定義了新的變量,則需要用代碼塊表示符號'{}'括起來,限定新定義變量的作用域,否則可能編譯階段報錯。
        switch (1) {
            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;
        }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM