[iOS] *** -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[1]

原來 Dictionary 不能放null, 真是長知識了。


NSDictionary and other collections cannot contain nil values. When NSDictionary must store a null, a special value [NSNull null] is stored.

Compare the value at @"My Data" to [NSNull null] to determine if the corresponding value is null or not.

// Since [NSNull null] is a singleton, you can use == instead of isEqual
if ([details objectForKey:@"My Data"] == [NSNull null]) {
    // Display the alert

It looks like you have a dangling or wild pointer.

You can consider Objective-C objects as pointers to structs.

You can then of course compare them with NULL, or with other pointers.


( myDict == NULL )


( myDict == [ NSNull null ] )

are both valid.

The first one will check if the pointer is NULL. NULL is usually defined as a void * with a value of 0.
Note that, for Objective-C objects, we usually use nil. nil is also defined as a void * with a value of 0, so it equals NULL. It’s just here to denote a NULL pointer to an object, rather than a standard pointer.

The second one compares the address of myDict with the singleton instance of the NSNullclass. So you are here comparing two pointers values.

So to quickly resume:

NULL == nil == Nil == 0

And as [ NSNull null ] is a valid instance:

NULL != [ NSNull null ]

Now about this:

( [ myDict count ] == 0 )

It may crash if you have a wild pointer:

NSDictionary * myDict;

[ myDict count ];

Unless using ARC, it will surely crash, because the myDict variable has not been initialised, and may actually point to anything.

It may also crash if you have a dangling pointer:

NSDictionary * myDict;

myDict = [ [ NSDictionary alloc ] init ];

[ myDict release ];
[ myDict count ];

Then you’ll try to send a message to a deallocated object.
Sending a message to nil/NULL is always valid in Objective-C.

So it depends if you want to check if a dictionary is nil, or if it doesn’t have values (as a valid dictionary instance may be empty).

In the first case, compare with nil. Otherwise, checks if count is 0, and ensure you’re instance is still valid. Maybe you just forgot a retain somewhere.



 -(void)CheckDictionary:(NSMutableDictionary *)dic
    NSArray *Arr = [dic allKeys];
    for (int i = 0; i<Arr.count; i++)
        if ([[dic valueForKey:[Arr objectAtIndex:i]] isKindOfClass:[NSNull class]])
            [dic setObject:@"" forKey:[Arr objectAtIndex:i]];
        else if ([[dic valueForKey:[Arr objectAtIndex:i]] isKindOfClass:[NSDictionary class]])
            NSMutableDictionary *dict = [[dic valueForKey:[Arr objectAtIndex:i]] mutableCopy];
            [dic setObject:dict forKey:[Arr objectAtIndex:i]];
            [self CheckDictionary:dict];
        else if ([[dic valueForKey:[Arr objectAtIndex:i]] isKindOfClass:[NSMutableArray class]])
            NSMutableArray *Arr12 = [dic valueForKey:[Arr objectAtIndex:i]];
            for (int j = 0; j<Arr12.count; j++)
                if ([[Arr12 objectAtIndex:j] isKindOfClass:[NSDictionary class]])
                    NSDictionary *dict123 = [Arr12 objectAtIndex:j];
                    NSMutableDictionary *dict = [dict123 mutableCopy];
                    [Arr12 replaceObjectAtIndex:j withObject:dict];
                    [self CheckDictionary:dict];

And Just pass the whole dictionary when you call this method I hope it would be helpful!!

 NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:responseObject options: NSJSONReadingMutableContainers error: nil];
             if (dictionary)
                 NSMutableDictionary *dict = [dictionary mutableCopy];
                 [self CheckDictionary:dict];
                 dictionary = [NSDictionary dictionaryWithDictionary:dict];





發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *