¿Cómo recorrer una jerarquía anidada de NSDictionaries y NSArrays y convertir todo a copys mutables?

Tengo un NSDictionary que contiene instancias de muchos types diferentes de objects ( NSArrays , NSDictionaries , NSStrings , NSNumbers , etc …). Muchos de los NSStrings y NSStrings tienen sus propios NSArrays nesteds y NSArrays .

¿Cómo puedo recorrer toda la jerarquía, de arriba a abajo, y convertir TODAS las instancias de NSDictionaries y NSArrays en NSMutableDictionaries y NSMutableArrays , respectivamente?

¿Hay alguna function fácil de "hacer copys mutables" recursivamente de la que no tengo conocimiento? Si no es así, ¿solo necesito repetir el bucle y el tipo de verificación? ¿Puedo replace como voy o tengo que rebuild toda la jerarquía?

El siguiente método crea una copy anidada (profunda) mutable de arreglos nesteds, dictionarys y sets. También se puede usar para crear copys mutables de objects que no son de colección dentro de la jerarquía, como cadenas.

 @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)]) { // eg NSString return [self mutableCopy]; } else if ([self conformsToProtocol:@protocol(NSCopying)]) { // eg NSNumber return [self copy]; #endif } else { return self; } } @end 

Utilizarlo como

 NSDictionary *dict = ...; NSMutableDictionary *mdict = [dict deepMutableCopy]; 

(Las keys de dictionary no se copyn, solo los valores).

Estoy bastante seguro de que he visto algo así en SO, pero no puedo encontrarlo ahora mismo.

Si bien la respuesta de Anoop está bien (creo que tampoco la compilé), si su jerarquía de instancias es realmente una list de properties, puede usar NSPropertyListSerialization para deserializar un plist con contenedores mutables y / o nodos de hoja.

Esto networkinguciría a less líneas de código y probablemente sea más rápido que un descenso manual a través del gráfico de objects, pero esta solución solo tiene sentido si inicialmente deserializa el plist de alguna parte.

Para el NSDictionary externo, esto creará un downdown de 1 nivel.

Debe llamar a esto en un método y continuar para get todos los dict y 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]; } } 

No se verificó el comstackdor. Leer como algorithm

Si usó algún método del sistema operativo para crear el dictionary: estos methods a menudo tienen un parámetro que le permite crear objects mutables. Por ejemplo, la class serializador JSON tiene banderas para hacer que todos los dictionarys y matrices sean mutables, y para hacer que todos los objects NSString sean mutables (NSNumber y NSNull nunca son mutables).