0

i have two NSMutableDictionaries

//ServiceResponse is NSMutableDictionary

     NSMutableDictionary *LocalDict=[[NSMutableDictionary alloc]initWithDictionary:serviceResponse];

When i made some changes in LocalDict then ServiceResponse is also changing.i think LocalDict is taking the reference of serviceResponse.i made many changes but unable to solve this problem. please tell me how i can sort out this prob. why the changes occuring in serviceResponse.

            if ([[[serviceResponse valueForKey:@"GetAllDetailsResult"]objectAtIndex:0]valueForKey:@"Products"]!=[NSNull null]) {
                if ([[[[serviceResponse valueForKey:@"GetAllDetailsResult"]objectAtIndex:0]valueForKey:@"Products"]count]>0) {
                    if ([[[[[serviceResponse valueForKey:@"GetAllDetailsResult"]objectAtIndex:0]valueForKey:@"Products"] objectAtIndex:0]valueForKey:@"OutputProductsDetails"]!=[NSNull null]) {

                        NSMutableDictionary *LocalDict=[[NSMutableDictionary alloc]initWithDictionary:serviceResponse];


                        for (int j=0; j< [[[[[[LocalDict valueForKey:@"GetAllDetailsResult"]objectAtIndex:0]valueForKey:@"Products"] objectAtIndex:0]valueForKey:@"OutputProductsDetails"] count] ;j++) {

                            for (int i=1; i<=5; i++) {

                                NSURL * imageURL = [NSURL URLWithString:[[[[[[[LocalDict valueForKey:@"GetAllDetailsResult"]objectAtIndex:0]valueForKey:@"Products"] objectAtIndex:0]valueForKey:@"OutputProductsDetails"]objectAtIndex:j] valueForKey:[NSString stringWithFormat:@"ThumbNailImage%d",i]]];

                                if (![[imageURL absoluteString]isEqualToString:@""]) {

                                    NSData * imageData = [[NSData alloc] initWithContentsOfURL:imageURL];

                                    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
                                    NSString *documentsDirectory = [paths objectAtIndex:0];
                                    NSString *savedImagePath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@%d.png",[[[[[[[LocalDict valueForKey:@"GetAllDetailsResult"]objectAtIndex:0]valueForKey:@"Products"] objectAtIndex:0]valueForKey:@"OutputProductsDetails"]objectAtIndex:j] valueForKey:@"ProductID"],i]];

                                    [imageData writeToFile:savedImagePath atomically:NO];

                                    [[[[[[[LocalDict valueForKey:@"GetAllDetailsResult"]objectAtIndex:0]valueForKey:@"Products"] objectAtIndex:0]valueForKey:@"OutputProductsDetails"]objectAtIndex:j]setValue:savedImagePath forKey:[NSString stringWithFormat:@"ThumbNailImage%d",i]];

                                }

                            }
                        }


                        [dbManager insertProductsDetails:[[[[[LocalDict valueForKey:@"GetAllDetailsResult"]objectAtIndex:0]valueForKey:@"Products"] objectAtIndex:0]valueForKey:@"OutputProductsDetails"]];

                    }
                }                    
            }

            /*
             *  Favourites details
             */
            if ([[[serviceResponse valueForKey:@"GetAllDetailsResult"]objectAtIndex:0]valueForKey:@"Favourite"]!=[NSNull null]) {
                if ([[[[serviceResponse valueForKey:@"GetAllDetailsResult"]objectAtIndex:0]valueForKey:@"Favourite"]count]>0) {
                    if ([[[[[serviceResponse valueForKey:@"GetAllDetailsResult"]objectAtIndex:0]valueForKey:@"Favourite"] objectAtIndex:0]valueForKey:@"OutputProductsDetails"]!=[NSNull null]) {
                        [dbManager insertFavouritesDetails:[[[serviceResponse valueForKey:@"GetAllDetailsResult"]objectAtIndex:0]valueForKey:@"Favourite"]];
                    }
                }                    
            }

            /*
             *  Rep Details
             */
            if ([[[serviceResponse valueForKey:@"GetAllDetailsResult"]objectAtIndex:0]valueForKey:@"RepDetails"]!=[NSNull null]) {
                if ([[[[serviceResponse valueForKey:@"GetAllDetailsResult"]objectAtIndex:0]valueForKey:@"RepDetails"]count]>0) {
                    if ([[[[[serviceResponse valueForKey:@"GetAllDetailsResult"]objectAtIndex:0]valueForKey:@"RepDetails"] objectAtIndex:0]valueForKey:@"OutputProductsDetails"]!=[NSNull null]) {
                        [dbManager insertRepUserDetails:[[[serviceResponse valueForKey:@"GetAllDetailsResult"]objectAtIndex:0]valueForKey:@"RepDetails"]];
                    }
                }
            }
rmaddy
  • 314,917
  • 42
  • 532
  • 579
garry007
  • 49
  • 9
  • try to set the Service Response dictionary against a key in your localDictionary. – Ashim Jun 24 '13 at 09:05
  • 2
    what a horrible data structure... because localDictionary is not a deep copy of serviceResponse, you should make the deep copy you own – adali Jun 24 '13 at 09:06
  • but i need the same format as the service Response dictionary.Is any other way without changing format i can do this ? – garry007 Jun 24 '13 at 09:08

3 Answers3

0

try this

 NSMutableDictionary *LocalDict=[[[NSMutableDictionary alloc]initWithDictionary:serviceResponse] mutableCopy];

Note: it makes a shallow copy. It isn't going to make immutable objects within your mutable dictionary.

hope that helps.

Tala
  • 8,888
  • 5
  • 34
  • 38
  • You should have mentioned what you already tried and not voting down when someone tries to help you based on info given. – Tala Jun 24 '13 at 09:15
  • And you should not accuse people of downvoting. Hint: It was not him ;-) – Matthias Bauch Jun 24 '13 at 09:20
  • ok, I was wrong. Just hope to see what's wrong with the answer so that we can all benefit. – Tala Jun 24 '13 at 09:22
  • The only difference between `[dict mutableCopy]` and `[NSMutableDictionary alloc] initWithDictionary:dict]` is that the latter returns a NSMutableDictionary even if dict is nil. – Matthias Bauch Jun 24 '13 at 09:33
0

this answer can solve your problem by deep copy

how to do true deep copy for NSArray and NSDictionary with have nested arrays/dictionary?

this is a good Category

@implementation NSDictionary (SPDeepCopy)

- (NSDictionary*) deepCopy {
    unsigned int count = [self count];
    id cObjects[count];
    id cKeys[count];

    NSEnumerator *e = [self keyEnumerator];
    unsigned int i = 0;
    id thisKey;
    while ((thisKey = [e nextObject]) != nil) {
        id obj = [self objectForKey:thisKey];

        if ([obj respondsToSelector:@selector(deepCopy)])
            cObjects[i] = [obj deepCopy];
        else
            cObjects[i] = [obj copy];

        if ([thisKey respondsToSelector:@selector(deepCopy)])
            cKeys[i] = [thisKey deepCopy];
        else
            cKeys[i] = [thisKey copy];

        ++i;
    }

    NSDictionary *ret = [[NSDictionary dictionaryWithObjects:cObjects forKeys:cKeys count:count] retain];

    // The newly-created dictionary retained these, so now we need to balance the above copies
    for (unsigned int i = 0; i < count; ++i) {
        [cObjects[i] release];
        [cKeys[i] release];
    }

    return ret;
}
- (NSMutableDictionary*) mutableDeepCopy {
    unsigned int count = [self count];
    id cObjects[count];
    id cKeys[count];

    NSEnumerator *e = [self keyEnumerator];
    unsigned int i = 0;
    id thisKey;
    while ((thisKey = [e nextObject]) != nil) {
        id obj = [self objectForKey:thisKey];

        // Try to do a deep mutable copy, if this object supports it
        if ([obj respondsToSelector:@selector(mutableDeepCopy)])
            cObjects[i] = [obj mutableDeepCopy];

        // Then try a shallow mutable copy, if the object supports that
        else if ([obj respondsToSelector:@selector(mutableCopyWithZone:)])
            cObjects[i] = [obj mutableCopy];

        // Next try to do a deep copy
        else if ([obj respondsToSelector:@selector(deepCopy)])
            cObjects[i] = [obj deepCopy];

        // If all else fails, fall back to an ordinary copy
        else
            cObjects[i] = [obj copy];

        // I don't think mutable keys make much sense, so just do an ordinary copy
        if ([thisKey respondsToSelector:@selector(deepCopy)])
            cKeys[i] = [thisKey deepCopy];
        else
            cKeys[i] = [thisKey copy];

        ++i;
    }

    NSMutableDictionary *ret = [[NSMutableDictionary dictionaryWithObjects:cObjects forKeys:cKeys count:count] retain];

    // The newly-created dictionary retained these, so now we need to balance the above copies
    for (unsigned int i = 0; i < count; ++i) {
        [cObjects[i] release];
        [cKeys[i] release];
    }

    return ret;
}

@end
Community
  • 1
  • 1
adali
  • 5,977
  • 2
  • 33
  • 40
0

Well i tried this and it solved my problem . Thnks every1 for their suggestions and help.

                NSData *buffer;
                  NSMutableDictionary *dictLocal;

                        // Deep copy "all" objects in _dict1 pointers and all to _dict2
                buffer = [NSKeyedArchiver archivedDataWithRootObject: serviceResponse];
                dictLocal = [NSKeyedUnarchiver unarchiveObjectWithData: buffer];  
garry007
  • 49
  • 9