I am trying to create a deep-copy of a NSMutableDictionary and assign it to another NSMutableDictionary. The dictionary contains a bunch of arrays, each array containing names, and the key is an alphabet (the first letter of those names). So one entry in the dictionary is 'A' -> 'Adam', 'Apple'. Here's what I saw in a book, but I'm not sure if it works:

- (NSMutableDictionary *) mutableDeepCopy
{
    NSMutableDictionary * ret = [[NSMutableDictionary alloc] initWithCapacity: [self count]];
    NSArray *keys = [self allKeys];

    for (id key in keys)
    {
        id oneValue = [self valueForKey:key]; // should return the array
        id oneCopy = nil;

        if ([oneValue respondsToSelector: @selector(mutableDeepCopy)])
        {
            oneCopy = [oneValue mutableDeepCopy];
        }
        if ([oneValue respondsToSelector:@selector(mutableCopy)])
        {
            oneCopy = [oneValue mutableCopy];
        }

        if (oneCopy == nil) // not sure if this is needed
        {   
            oneCopy = [oneValue copy];
        }
        [ret setValue:oneCopy forKey:key];

        //[oneCopy release];
    }
    return ret;
}
  • [onecopy版本]是否应该存在?
  • 下面是我将如何调用这个方法:

    self.namesForAlphabets = [self.allNames mutableDeepCopy];

可以吗?还是会导致泄漏?(假设我将self.namesForAlphabets声明为属性,并在dealloc中释放它).

推荐答案

IMPORTANT:问题(以及我下面的代码)都涉及一个非常具体的情况,其中NSMutableDictionary包含only个字符串array.这些解决方案适用于更复杂的示例.有关更一般的 case 解决方案,请参见以下内容:


Answer for this specific case:

你的代码应该可以工作,但你肯定需要[oneCopy release].新字典将在您使用setValue:forKey添加复制的对象时保留这些对象,因此如果您不调用[oneCopy release],所有这些对象将保留两次.

一个很好的经验法则:如果你是allocretaincopy岁左右的人,你也必须是release岁.

注意:下面是一些可以工作for certain cases only次的示例代码.这是因为NSMutableDictionary只包含字符串数组(不需要进一步的深度复制):

- (NSMutableDictionary *)mutableDeepCopy
{
    NSMutableDictionary * ret = [[NSMutableDictionary alloc]
                                  initWithCapacity:[self count]];

    NSMutableArray * array;

    for (id key in [self allKeys])
    {
        array = [(NSArray *)[self objectForKey:key] mutableCopy];
        [ret setValue:array forKey:key];
        [array release];
    }

    return ret;
}

Objective-c相关问答推荐

应用程序终止时处理推送通知

Objective-c 点表示法或方括号表示法中首选什么?

将 NSInteger 变量传递给 NSMutableDictionary 或 NSMutableArray

验证应用内购买的收据

NSLocalizedString 格式

NSPredicate 与整数比较

ios 13 - 带有 UISearchBar _searchField 的自定义 SearchBar 不起作用

使用 NSMutableArray 的二维数组

iOS 中 textField 上的Electron邮件验证

iOS 7 - viewDidLoad 和 viewDidAppear 之间的区别

通过 ObjC 类别覆盖方法并调用默认实现?

更改 UIBarButtonItem 的 Tint colored颜色

如何删除手势识别器

如何在 Objective-C (iOS) 中判断 NaN 值

通过索引访问 NSMutableDictionary 中的对象

Highlighted 和 Selected UIButton 的 State 有什么区别?

Xcode 的不完整实现警告

在 iOS 6.0 的 Xcode 4.5 中我没有要求的日志(log)消息

CALayer:仅在一侧添加边框

UICollectionView:如何检测滚动何时停止