在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循环逻辑吗?我不确定他在查看哪个值响应哪个选择器以及为什么将它添加到字典中时尝试做什么。感谢。
答案 0 :(得分:3)
因此,for循环只是遍历字典中的所有键。在此之前,我们创建了一个名为returnDict
的新词典 - 这将是我们返回的词典。
对于我们要复制的字典中的每个键,我们......
获取为该密钥存储的对象([self valueForKey:key]
),并将其保存到名为oneValue
的变量中。
如果oneValue
实现了我们的mutableDeepCopy
方法(即,它是NSDictionary
),请调用它,并将返回值分配给名为oneCopy
的变量。
否则,我们会看到oneCopy
是否实现了mutableCopy
方法。如果是,我们将输出放入oneCopy
变量。
此时,我们检查以下步骤(2)和(3){@ 1}}变量是否分配了任何内容(oneCopy
)。如果它没有(即,它等于if (oneCopy == nil)
),我们可以假设该对象没有实现nil
或mutableDeepCopy
,所以我们改为调用普通的mutableCopy
并将其值分配给copy
。
使用原始密钥将oneCopy
添加到我们的oneCopy
字典中。
这就是for循环 - 在最后,我们返回复制的字典。
答案 1 :(得分:0)
for循环中的逻辑是复杂的,因为作者试图尽可能地获得整个数组的可变和深度。代码按优先顺序尝试三种不同的方式来满足这一要求:
mutableDeepCopy
(如果对象理解该消息)。mutableCopy
。copy
。如果对象只是普通的不可复制,那么当代码发送对象-copy
时,您的代码会变得繁荣,因为没有对对象是否响应-copy
进行测试。这是合适的,因为尝试深度复制包含无法复制的项目的数组肯定是程序员错误。