1. 程式人生 > >iOS開發陷阱之NSString

iOS開發陷阱之NSString

今天除錯程式的時候發現一個不應該進去的比較判斷進去了,檢視記憶體發現NString的值為nil進行compare比較居然返回NSOrderSame,於是想記載一下,上網查發現已經有前輩寫了,故偷懶,轉載於此。

------------------分割線-------------

原文連結:http://www.cnblogs.com/xinus/archive/2013/01/26/ios-dev-traps-nsstring-compare.html

NSString有多個compare相關方法:

- (NSComparisonResult)compare:(NSString *)string;
- (NSComparisonResult)compare:(NSString *)string
options:(NSStringCompareOptions)mask; - (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask range:(NSRange)compareRange; - (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask range:(NSRange)compareRange locale:(id)locale;

NSComparisonResult

 是定義的一個列舉,定義如下:

typedef NS_ENUM(NSInteger, NSComparisonResult) {NSOrderedAscending = -1L, NSOrderedSame, NSOrderedDescending};

其中,NSOrderedSame 表示比較的兩個字串完全一致, 同時,在這個列舉中,它的值是 0.

字串比較在程式中很常見,比如:

    if ([str1 compare:@"some text"] == NSOrderedSame) {
        // Do something
    }
    else {
        
// Do something else }

但,如果如上中的str1為nil,根據Objective-C的訊息呼叫規則(方法呼叫),對nil傳送的任何訊息,得到的返回都是nil。這樣的情況下,執行時是不會像C/C++那樣,出現空指標的非法訪問而使得程式強行終止。也就是說,在Objective-C下面,即便str1為nil,也不會造成程式崩潰,而是會繼續執行。

那麼當str1為空的時候,[str1 compare:@"some text"] 訊息的返回就會為nil。nil表示一個空的Objective-C物件,實際就是表示一個空指標,而它代表的值就是0,與NSOrderedSame的值相等. 如此,回到最前面的if語句,如果str1為nil,那麼整個語句的值為真。這會給程式造成非常嚴重的問題,小則邏輯錯誤,UI顯示錯誤等,大則會造成資料洩漏等等。。。所以,一旦出現這種情況,還是很嚴重的。

筆者個人建議,以上程式碼至少應該寫為:

    if (str1!=nil && [str1 compare:@"some text"] == NSOrderedSame) {
        // Do something
    }
    else {
        // Do something else
    }