2011-05-29 61 views
1

在Beginning iPhone 4手冊中,作者使用此代碼創建一個類別,用於創建一個NSDictionary的深層副本,該副本具有字母表中每個字母的NSArray名稱,以顯示帶有搜索欄的索引表。關於深拷貝示例的問題

#import "NSDictionary-MutableDeepCopy.h" 
@implementation NSDictionary (MutableDeepCopy) 
- (NSMutableDictionary *) mutableDeepCopy { 
    NSMutableDictionary *returnDict = [[NSMutableDictionary alloc] initWithCapacity:[self count]]; 
    NSArray *keys = [self allKeys]; 
    for (id key in keys) { 
     id oneValue = [self valueForKey:key]; 
     id oneCopy = nil; 
     if ([oneValue respondsToSelector:@selector(mutableDeepCopy)]) oneCopy = [oneValue mutableDeepCopy]; 
     else if ([oneValue respondsToSelector:@selector(mutableCopy)]) oneCopy = [oneValue mutableCopy]; 
     if (oneCopy == nil) 
      oneCopy = [oneValue copy]; 
     [returnDict setValue:oneCopy forKey:key]; 
     [oneCopy release]; 
    } 
    return returnDict; 
} 

@end 

有人可以解釋for循環邏輯嗎?我不確定他在查看哪個值響應哪個選擇器時會做什麼,以及爲什麼它會被添加到字典中。謝謝。

回答

3

因此,for循環只是遍歷字典中的所有鍵。之前,我們創建了一個名爲returnDict的新字典 - 這將是我們返回的內容。

對於我們要複製,我們的字典中的每個鍵...

  1. 獲取存儲該密鑰([self valueForKey:key])的對象,並將其保存到一個名爲oneValue變量。

  2. 如果oneValue實現我們的mutableDeepCopy方法(即,它是一個NSDictionary)去調用它,返回值分配到一個名爲oneCopy變量。

  3. 否則,我們看到如果oneCopy實施mutableCopy方法。如果是這樣,我們把輸出放入oneCopy變量中。

  4. 此時,我們檢查以下步驟(2)和(3)oneCopy變量是否已分配給它(if (oneCopy == nil))。如果不是(即等於nil),我們可以假定該對象不執行mutableDeepCopymutableCopy,因此我們改爲調用普通的舊copy並將其值分配給oneCopy

  5. 使用原始密鑰將oneCopy添加到我們的returnDict字典中。

這就是for循環 - 最後,我們將返回複製的字典。

0

for循環中的邏輯錯綜複雜,因爲作者試圖獲得儘可能多的可變數據和整個數組的拷貝。代碼試圖三種不同的方法,以滿足這一點,以優先順序:

  • 使用mutableDeepCopy如果可能的話(如果對象理解消息)。
  • 否則,如果可能,請使用mutableCopy
  • 如果一切都失敗了,只需使用copy

如果對象只是普通的沒有可複製的,你的代碼進入繁榮時,它發送的對象-copy,因爲沒有測試的對象是否響應-copy製造。這是合適的,因爲試圖深入複製包含無法複製項目的數組絕對是程序員錯誤。