Search code examples
objective-cnsdictionarynsnull

How to remove <null>'s from NSDictionary?


I'm trying to use the writeToFile method of an NSArray of NSDictionaries which doesn't allow nulls. I figured just loop through and find them and replace with empty NSString's but I can't get it to work. This is what I'm trying.

EDIT: The NSArrays and NSDictionaries are created by NSJSONSerialization.

for (NSMutableDictionary *mainDict in mainArray)
{
    for(NSMutableDictionary *subDict in mainDict)
    {
        for(NSString *key in subDict)
        {                
            id value = [subDict objectForKey:key];

            if (value == [NSNull null])
            {
                [subDict setObject:@"" forKey:key];
            }
        }
    }
}

But this throws an exception. *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[__NSCFDictionary setObject:forKey:]: mutating method sent to immutable object'

But as you can see all NSDictionaries are mutable.

What's up? Is there a better way to do this?

EDIT: Moved new version to a separate answer.


Solution

  • How do you know that the dictionaries are mutable? It looks like they’re not. Typing them as NSMutableDictionary during the enumeration doesn’t make them mutable. You could walk over the dictionary and move the keys into a new, mutable one, filtering the nulls.

    Also, if your dictionary comes from NSJSONSerialization, take a look at NSJSONReadingOptions, there’s an option to use mutable containers for the deserialized structure. That’s not always a good solution, but it’s worth checking out.

    As for mutating a dictionary while enumerating it: you can’t change the keys, since that could easily throw off the enumeration code. But I don’t see why you couldn’t change the key values, which is all you’re after. This code works:

    NSMutableDictionary *dict = [@{@"foo" : @"bar"} mutableCopy];
    for (NSString *key in dict) {
        dict[key] = @"baz";
    }