2012-05-21 41 views
4

我的理解方式是Objective C的一個特殊之處,就是你可以將消息發送到NULL,它會忽略它們而不是崩潰。爲什麼NSArray不爲不存在的索引返回NULL?

爲什麼NSArray不只是返回一個NULL對象,如果索引請求超出邊界而不是導致NSRangeException?

我期望Objective C和NSArray的內容如下。

NSArray *array = [NSArray arrayWithObjects:@"Object 1", @"Object 2", @"Object 3", nil]; 

for (int i = 0; i < 5; i++) { 
    NSString *string = [array objectAtIndex:i]; 

    if (string) { 
     NSLog(@"Object: %@",string); 
    } 
} 

讓我訪問數組的索引與不包含對象,並簡單地返回NULL。然後我可以檢查對象是否存在。我可以在其他地方做到這一點,例如檢查對象是否已經實例化。

NSArray *array; 

if (!array) { 
    array = [NSArray array]; 
} 

我意識到這是一個基於理論的問題,但我很好奇:)爲零

+2

消息傳遞nil與詢問出界指數完全不同。我不明白你爲什麼要在這裏建立聯繫。 –

+1

因爲它沒有意義。在您的程序分配的內容之外訪問內存是未定義的行爲。未定義的行爲不應該是程序依賴的東西,相反,它應該是程序努力去除的東西。誠然,NSArray不是一個數組,但它在大多數情況下必須遵循數組範例。 –

回答

9

消息是一種語言水平的功能,而不是一個框架,API的功能。

NSArray(和其他類)拋出一個異常以指示程序員錯誤是在設計API(〜1993)時做出的有意識的設計決定。正如Kevin和Richard所指出的那樣,nil eats message在任何情況下都不是錯誤的,而out of bounds就是錯誤輸入的情況。

你會在哪裏畫線? substringWithRange:應該接受任何舊的輸入? setObject:atIndex:怎麼樣?

通過使NSArray @throw處於indexOfObject:的邊界例外,它使API保持一致; 超出範圍的任何指數(或範圍)將爲@throw

+0

好的,謝謝你的解釋。只是我需要的東西。我是一名自學的程序員,沒有CS教育,所以這正是我所需要的。 –

+1

當然 - API設計有很多微妙之處。在很多情況下,看起來像是一個奇怪的決定,如果放到更大的背景中,就很有意義。 API設計和語言設計很難做到! – bbum

2

你可以使用NSMutableDictionary來完成你想要做的事情。將密鑰設置爲NSNumber索引。在不存在的鍵上調用objectForKey(不在我們想象的範圍內或刪除)將返回nil。

+1

謝謝,沒有專門尋找解決方案使其工作我一直有解決方法,我更正確的方式來處理它。只是好奇。 Upvote試圖解決一個雖然不存在的問題!大聲笑 –

+1

這涉及到另一個事實,就是你不能有一個稀疏的數組。返回nil來響應'-objectForKey:'的數組表明在該索引處有一個空的位置,而不是索引本身是無效的。還要注意,'[-NSDictionary objectForKey:]'@如果關鍵字爲零,則會拋出@。 – paulmelnikow

+0

這也使得NSMutableDictionary成爲一個很好的候選者,可以用作稀疏數組(如果需要的話)。 – Dima