关于深度复制示例的问题

时间:2011-05-29 18:21:15

标签: iphone objective-c categories nscoding

在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循环逻辑吗?我不确定他在查看哪个值响应哪个选择器以及为什么将它添加到字典中时尝试做什么。感谢。

2 个答案:

答案 0 :(得分:3)

因此,for循环只是遍历字典中的所有键。在此之前,我们创建了一个名为returnDict的新词典 - 这将是我们返回的词典。

对于我们要复制的字典中的每个键,我们......

  1. 获取为该密钥存储的对象([self valueForKey:key]),并将其保存到名为oneValue的变量中。

  2. 如果oneValue实现了我们的mutableDeepCopy方法(即,它是NSDictionary),请调用它,并将返回值分配给名为oneCopy的变量。

  3. 否则,我们会看到oneCopy是否实现了mutableCopy方法。如果是,我们将输出放入oneCopy变量。

  4. 此时,我们检查以下步骤(2)和(3){@ 1}}变量是否分配了任何内容(oneCopy)。如果它没有(即,它等于if (oneCopy == nil)),我们可以假设该对象没有实现nilmutableDeepCopy,所以我们改为调用普通的mutableCopy并将其值分配给copy

  5. 使用原始密钥将oneCopy添加到我们的oneCopy字典中。

  6. 这就是for循环 - 在最后,我们返回复制的字典。

答案 1 :(得分:0)

for循环中的逻辑是复杂的,因为作者试图尽可能地获得整个数组的可变和深度。代码按优先顺序尝试三种不同的方式来满足这一要求:

  • 如果可能,请使用mutableDeepCopy(如果对象理解该消息)。
  • 否则,请尽可能使用mutableCopy
  • 如果其他所有方法都失败了,只需使用copy

如果对象只是普通的不可复制,那么当代码发送对象-copy时,您的代码会变得繁荣,因为没有对对象是否响应-copy进行测试。这是合适的,因为尝试深度复制包含无法复制的项目的数组肯定是程序员错误。

相关问题