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

4

2 回答 2

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),我们可以假设该对象没有实现mutableDeepCopyor mutableCopy,因此我们改为调用普通 oldcopy并将其值分配给oneCopy.

  5. 使用原始键添加oneCopy到我们的字典中。returnDict

这就是 for 循环——最后,我们返回复制的字典。

于 2011-05-29T18:31:17.640 回答
0

for 循环中的逻辑很复杂,因为作者试图尽可能多地获取整个数组的可变副本和深度副本。该代码按优先顺序尝试了三种不同的方法来满足这一点:

  • 尽可能使用mutableDeepCopy(如果对象理解该消息)。
  • 否则,mutableCopy尽可能使用。
  • 如果一切都失败了,只需使用copy.

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

于 2011-05-29T20:18:29.323 回答