I have the following code fragment:
NSString* value = @\"value\";
NSString* key = @\"key\";
NSMutableDictionary* foo = [NSMutableDictionary dictionary];
NSDictio
If you really don't care if it's mutable, but want to mutate it anyway, you could try this:
NSString* value = @"value";
NSString* key = @"key";
NSDictionary* bar = [NSDictionary dictionary];
NSLog(@"bar desc: %@", [bar description]);
NSMutableDictionary* temp = [bar mutableCopy];
[temp setValue:value forKey:key];
bar = temp;
NSLog(@"bar desc: %@", [bar description]);
If you need to guarantee that a dictionary is mutable, you should:
Determining whether an NSDictionary is mutable before attempting to modify its keys and/or values can be considered an example of a code smell, indicating that there's a deeper problem that should be solved. In other words, you should always know whether a given dictionary instance is NSDictionary or NSMutableDictionary. The code should be clear on that point.
Honestly, you can't easily tell the difference without a @try
block. Standard practice is as follows:
copy
the dictionary. If it's really non-mutable, the frameworks will optimize that into a retain
. If it really was mutable, then you probably wanted a copy anyway.It's pretty simple actually, all you need to do is test against the member of the class, like this:
if ([bar isMemberOfClass:[NSMutableDictionary class]]){
[bar setValue:value forKey: key];
}
iPhone SDK difference between isKindOfClass and isMemberOfClass
NSAssert([bar isMemberOfClass: [NSMutableDictionary class]], @"");
I end up using @try catch but it only fires once. So it works like this
NSMutableDictionary *valuesByIdMutable = (id)self.valuesById;
simplest_block block = ^{
[valuesByIdMutable setObject:obj forKey:key];
};
@try {
block();
} @catch (NSException *exception) {
self.valuesById = valuesByIdMutable = [valuesByIdMutable mutableCopy];
block();
}