Reputation: 1387
I have an NSMutableDictionary
with a dozen keys, each key refers to an NSString
value. If I call [myDictionary valueForKey:@"abc"]
I will get an NSString
object.
Is this NSString
copied?
As there is no @property
declaration, what happens with this retrieval of the string? I assume I get a copy. Is it any different with a NSMutableString
?
My purpose is that I have an array of NSDictionaries
. I call valueForKey
on the array to get all the @"abc" keys from the collection of dictionaries. Thus I now have an array of NSStrings.
I need to pass that array to an NSOperation
on a background thread. Thus, the NSStrings
need to be copies so that modifying the dictionaries later will not cause the ones passed to the NSOperation
to get changed.
Upvotes: 0
Views: 294
Reputation: 3439
NSDictionary
keys are copied when set. In the code dictionary[key] = value
the key
object is copied, and the dictionary retains the copy. The value
object is not copied; the caller and the dictionary share a reference to the same object.
When retrieving keys or object, there is no copying. dictionary.allKeys
returns an array of the key objects in the dictionary, not copies. Similarly, dictionary[key]
returns a reference to the value for key
in the dictionary.
And just so you know, the @property (copy)
only applies when setting the value. ObjC getters never copy objects, unless it is specifically documented that way or you write your own so it does that.
Similarly, and to get to your question, key-value method use the same underlaying rules for that property. So -setValue:forKey:
, -setValue:forKeyPath:
, -valueForKey:
, -valueForKeyPath:
etc. will get or set the proper value as if you accessed the property directly. In other words, if the value is copied when the property is set, -setValue:forKeyPath:
will copy the value. If an accessor does not copy the value, then -valueForKey:
will not copy the value.
Upvotes: 1
Reputation: 15589
From the documentation of -[NSDictionary valueForKey:]
:
If key does not start with “@”, invokes objectForKey:. If key does start with “@”, strips the “@” and invokes [super valueForKey:] with the rest of the key.
From the documentation of -[NSMutableDictionary setObject:forKey:]
:
If aKey already exists in the dictionary, anObject takes its place.
valueForKey:
does objectForKey:
and does not copy the object. setObject:forKey:
replaces the object, it does not modify the object. If you do
[mutableDictionary setObject:@"klm" forKey:@"abc"];
a = [mutableDictionary valueForKey:@"abc"];
[mutableDictionary setObject:@"xyz" forKey:@"abc"];
now a
is the old value @"klm"
.
Upvotes: 1