NSMutableDictionary的深度可变副本 [英] deep mutable copy of a 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 withsetValue: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
orcopy
something, you must alsorelease
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屋!