我有一个NSDictionary
,其中包含许多不同类型对象的实例(NSArrays
,NSDictionaries
,NSStrings
,NSNumbers
等等。许多NSDictionaries
和NSStrings
都有自己的嵌套NSDictionaries
和NSArrays
。
如何从上到下循环遍历整个层次结构,并将NSDictionaries
和NSArrays
的所有实例分别转换为NSMutableDictionaries
和NSMutableArrays
?
有什么简单的“递归制作可变副本”功能我不知道吗?如果没有,我是否只需要反复循环和键入检查?我可以随时更换,还是重建整个层次结构?
答案 0 :(得分:18)
以下方法创建嵌套数组,字典和集的嵌套(深层)可变副本。它还可用于在层次结构内创建非集合对象的可变副本,例如字符串。
@interface NSObject (MyDeepCopy)
-(id)deepMutableCopy;
@end
@implementation NSObject (MyDeepCopy)
-(id)deepMutableCopy
{
if ([self isKindOfClass:[NSArray class]]) {
NSArray *oldArray = (NSArray *)self;
NSMutableArray *newArray = [NSMutableArray array];
for (id obj in oldArray) {
[newArray addObject:[obj deepMutableCopy]];
}
return newArray;
} else if ([self isKindOfClass:[NSDictionary class]]) {
NSDictionary *oldDict = (NSDictionary *)self;
NSMutableDictionary *newDict = [NSMutableDictionary dictionary];
for (id obj in oldDict) {
[newDict setObject:[oldDict[obj] deepMutableCopy] forKey:obj];
}
return newDict;
} else if ([self isKindOfClass:[NSSet class]]) {
NSSet *oldSet = (NSSet *)self;
NSMutableSet *newSet = [NSMutableSet set];
for (id obj in oldSet) {
[newSet addObject:[obj deepMutableCopy]];
}
return newSet;
#if MAKE_MUTABLE_COPIES_OF_NONCOLLECTION_OBJECTS
} else if ([self conformsToProtocol:@protocol(NSMutableCopying)]) {
// e.g. NSString
return [self mutableCopy];
} else if ([self conformsToProtocol:@protocol(NSCopying)]) {
// e.g. NSNumber
return [self copy];
#endif
} else {
return self;
}
}
@end
像
一样使用它NSDictionary *dict = ...;
NSMutableDictionary *mdict = [dict deepMutableCopy];
(不复制字典键,只复制值。)
我很确定我在SO上看过类似的东西,但现在找不到它。
答案 1 :(得分:2)
虽然Anoop的答案很好(我想,我也没有编译它),如果您的实例层次结构实际上是属性列表,那么您可以使用NSPropertyListSerialization反序列化具有可变容器的plist /或叶节点。
这会减少到更少的代码行,并且可能比通过对象图的手动下降更快,但是这个解决方案只有在你最初从某个地方反序列化plist时才有意义。
答案 2 :(得分:1)
对于外部NSDictionary,这将创建1级向下。
您需要在方法中调用此方法,然后继续获取所有dict
和array
。
NSMutableDictionary *dict=[NSMutableDictionary new];
NSMutableArray *array=[NSMutableArray new];
for(NSDictionary *dict in yourMainDictionary){
if([outerDict[dict] class]==[NSDictionary class]){
[dict setObject:outerDict[dict] forKey:dict];
}
else if([outerDict[dict] class]==[NSArray class]){
array[array.count]=outerDict[dict];
}
}
未编译器已检查。读作算法
答案 3 :(得分:1)
如果您使用某种操作系统方法来创建字典:这些方法通常具有允许您创建可变对象的参数。例如,JSON序列化程序类具有使所有字典和数组可变的标志,并使所有NSString对象可变(NSNumber和NSNull永远不可变)。