2013-07-07 22 views
0

我有一個for循環。Obj-C/Cocoa如何檢查[string characterAtIndex:i]是否返回NSRangeException?

for (i=0; i <= stringLength; i++) { 

unichar currentCharacter = [string characterAtIndex:i]; 

...} 

我從characterAtIndex文檔理解:通常將返回類型「單字符」的價值,但如果我們的指數超出範圍則返回NSRangeException。

由於小心謹慎,我想檢查是否[字符串characterAtIndex:我]被分配到價值迴歸currentCharacter前返回一個NSRangeException與否。

我想的第一件事情是這樣的:

if ([string characterAtIndex:i] != NSRangeException) 

...但它不工作,因爲,從我的理解,該方法通常返回一個int,我比較它NSRangeException,這是一個字符串。

我想過[字符串characterAtIndex:i] isKindOfClass:...]但這不起作用,因爲[字符串characterAtIndex:i]不是NSObject。那麼,呃,我如何測試異常?

我應該測試例外嗎?我如何測試返回值的類型,如果它有時是原始的,有時是NSObject?

+1

異常與普通的Objective-C變量完全不同。雖然它們是名義上的物體,但它們的處理方式不同並且「有信號」,而不是在通話中返回。儘管有時候可以在Objective-C中「處理」一個異常,但它最好還是可以的,並且避免它們好得多。要避免characterAtIndex的範圍異常,請確保您的索引值大於等於0且嚴格小於字符串長度。 –

回答

1

嗨奧利弗, 我只是偶然發現了這個問題,我想我會回答這個問題,但我希望,因爲你已經工作了,並沒有被卡在這6個月;)

首先,假設stringLength == [string length],那麼你需要檢查該指數是嚴格小於 stringLength,不小於或等於,即:

for (i=0; i < stringLength; i++) { 

    unichar currentCharacter = [string characterAtIndex:i]; 

...} 

舉個例子,一個5個字符的字符串有5個有效索引; 0,1,2,3和4.

該修復程序應該會阻止您獲取異常,但這裏是對異常的更多解釋(我在編寫索引前注意到您的錯誤):

例外不像正常返回值,它們就像一個特別緊急信道,通過該功能,可以通知其的一個錯誤條件呼叫者,而不必堵塞錯誤狀態到其正常的返回值。

的術語是異常不「返回」這麼多,因爲他們是「上調」或「拋出」(取決於語言)。然後「抓住」或「從中救出」的異常(取決於語言)。

例外只能在特殊情況下使用,如果有避免異常(由消毒輸入)的一些方法你應該做的第一。在可能的情況下避免異常的另一個原因是,在某些語言中,捕獲異常的過程並不是非常有效,並且還可以使存儲器分配略微高出一點。

但在特殊情況下,他們發出錯誤信號至調用功能,而無需圖謀在返回值的範圍內表達錯誤情況的某種方式的有效途徑。

於是,就到了實用性。捕捉你的情況的例外是語法:

@try { 
    for (i=0; i <= stringLength; i++) { 
    unichar currentCharacter = [string characterAtIndex:i]; 
    } 
} 
@catch (NSException *exception) { 
    NSLog(@"uh oh.."); 
    // handle the exception here 
} 

,將捕獲任何拋出異常,不只是NSRangeException。在許多語言中,您可以更有選擇性地使用像@catch (NSRangeException *exception)這樣的語法,但不幸的是不在Objective-C中。這是因爲NSRangeException沒有被定義爲NSException的子類,而是一個NSString常量,它將出現在NSException的-name值中。要在Objective-C更具有選擇性,你需要做的是這樣的:

@catch (NSException *exception) { 
    if ([[exception name] isEqualToString:NSRangeException]) { 
    NSLog("got an NSRangeException"); 
    // handle the exception here 
    } else { 
    NSLog("got an exception we can't handle so pass it down the chain"); 
    @throw exception; 
    } 
} 

正如你所看到的,它可以得到相當笨拙的捕捉異常,因此它總是最好儘量避開他們。如果此代碼觸發NSRangeException,一些非常特殊的(也可能是你無法控制的)必須發生的事情:

for (i=0; i < [string length]; i++) { 

    unichar currentCharacter = [string characterAtIndex:i]; 

...} 
0

這也是值得注意的,你應該基本上不與可變字符串做到這一點。製作一個不可變的副本。如果你真的想用不可變的字符串來嘗試,你應該從最後迭代。在for循環迭代條件中聲明長度沒有改變也是合理的。