NSMutableDictionary的深度可变副本 [英] deep mutable copy of a NSMutableDictionary

查看:110
本文介绍了NSMutableDictionary的深度可变副本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建NSMutableDictionary的深层副本并将其分配给另一个NSMutableDictionary。字典包含一堆数组,每个数组包含名称,键是字母表(这些名称的第一个字母)。因此字典中的一个条目是'A' - >'Adam','Apple'。这是我在书中看到的,但我不确定它是否有效:

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 release]存在或者不是吗?

  • 以下是我将如何调用此方法:

    • should the [onecopy release] be there or not?
    • Here's how I'm going to call this method:

      self。 namesForAlphabets = [self.allNames mutableDeepCopy];

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

      Will that be ok? Or will it cause a leak? (assume that I declare self.namesForAlphabets as a property, and release it in dealloc).

      推荐答案

      重要:问题(以及我的代码)都涉及一个非常具体的案例,其中NSMutableDictionary包含字符串数组。对于更复杂的示例,这些解决方案将不起作用。有关更一般的案例解决方案,请参阅以下内容:

      IMPORTANT: The question (and my code below) both deal with a very specific case, in which the NSMutableDictionary contains only arrays of strings. These solutions will not work for more complex examples. For more general case solutions, see the following:

      • Tom Dalling's answer
      • dreamlax's answer
      • Source from yfujiki on GitHub Gist

      这个具体案例的答案:

      您的代码应该可以使用,但您肯定需要 [oneCopy release] 。当您使用 setValue:forKey 添加复制对象时,新词典将保留复制的对象,因此如果您不调用 [oneCopy release] ,所有这些对象都会被保留两次。

      Your code should work, but you will definitely need the [oneCopy release]. The new dictionary will retain the copied objects when you add them with setValue:forKey, so if you do not call [oneCopy release], all of those objects will be retained twice.

      一个好的经验法则:如果你 alloc 保留复制的东西,你还必须发布它。

      A good rule of thumb: if you alloc, retain or copy something, you must also release it.

      注意:这里有一些示例代码仅适用于某些情况的 。这是有效的,因为你的NSMutableDictionary只包含字符串数组(不需要进一步深度复制):

      Note: here is some sample code that would work for certain cases only. This works because your NSMutableDictionary contains only arrays of strings (no further deep copying required):

      - (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;
      }
      

      这篇关于NSMutableDictionary的深度可变副本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆