0

I have declared an NSMutableArray *arrAllRecordsM and am trying to add NSMutableDictionary *dicRecordM to it using addObject. The dicRecordM gets added to arrAllRecordsM but on doing [dicRecordM removeAllObjects] it sets to nil in arrAllRecordsM. Below is the code, please help me fix it.

self.arrAllRecordsM = [NSMutableArray array];
self.dicRecordM = [NSMutableDictionary dictionary];

// Some Method

[self.dicRecordM setObject:@"Test" forKey:@"ADDRESS"];
[self.arrAllRecordsM addObject:self.dicRecordM];

// Value: Test
NSLog(@"Value: %@", [[self.arrAllRecordsM objectAtIndex:0] valueForKey:@"ADDRESS"]);
[self.dicRecordM removeAllObjects];

// Value: null
NSLog(@"Value: %@", [[self.arrAllRecordsM objectAtIndex:0] valueForKey:@"ADDRESS"]); 
1
  • 2
    Your code is behaving correctly. Why do you expect a different result? You are trying to obtain a nonexistent value. Of course it's going to return nil. Commented Nov 24, 2013 at 17:57

2 Answers 2

4

Adding an object to an NSMutableArray just stores a pointer (or "strong reference") to the object into the array. Therefore

[self.arrAllRecordsM objectAtIndex:0]

and

self.dicRecordM

are two pointers to the same object. If your remove all key/value pairs from self.dicRecordM then [self.arrAllRecordsM objectAtIndex:0] still points to the same (now empty) dictionary. That is the reason why

[[self.arrAllRecordsM objectAtIndex:0] valueForKey:@"ADDRESS"]

returns nil.

If you want an independent copy of the dictionary in the array, use

[self.arrAllRecordsM addObject:[self.dicRecordM copy]];

copy can be used on many classes, such as NSDictionary, NSArray and NSString and their mutable variants, to get a "functionally independent object". Formally, it is available for all classes conforming to the NSCopying protocol.

Sign up to request clarification or add additional context in comments.

Comments

1

This is expected behavior. You removed all the objects from the dictionary by calling removeAllObjects, then tried to retrieve an object from it and rightfully getting nil, since it doesn't exist in the dictionay anymore (you removed it).

What's maybe unclear to you is that NSArray doesn't copy the element you add to it, instead it just holds a strong reference.

So both dicRecordM and arrAllRecordsM are holding a reference to the same object, hence any modification to it (in this case removeAllObjects) will affect the same dictionary.


Incidentally, you shouldn't use valueForKey: for accessing the dictionary's entries. Use objectForKey: or the shorter subscripted syntax. For instance

self.arrAllRecordsM[0][@"ADDRESS"]

You can read this answer Difference between objectForKey and valueForKey? as a reference, but the main problem is that valueForKey: can behave very differently from objectForKey: in case the key contains special KVC characters, such as @ or ..

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.