Tricky stuff of NSMutableDictionary24 Nov 2013 | iOS
I went into a quite tricky trouble caused by
I took use of MagicalRecord to manage my Core Data. However, when saving the context, the data cannot be persisted. An error log as following appeared:
NO CHANGES IN CONTEXT on *** BACKGROUND THREAD *** - NOT SAVING
And my codes look like following:
NSMutableDictionary *dict = entity.dict; [dict setObject:obj_a forKey:@"task"]; [dict setObject:obj_b forKey:@"info"]; [[NSManagedObjectContext contextForCurrentThread] saveToPersistentStoreAndAwait]; obj_a and obj_b are two NSDictionarys.
When I changed the content of Obj_a and Obj_b, and then call the persist method, the above error occurs. After several careful checks, I found out that even before line.2, the op output of dict was still the latest(which is what I supposed it to be after line.3, that means line.2 and line.3 are useless). That made me realize the setObject:forKey: method will only save a pointer to the object instead of make a deep copy of that. And that explains why [NSManagedObjectContext hasChanges] always returns NO. Although the content of obj_a and obj_b were changed, its address remained unchanged. As the -hasChanges method took use of key-value-observing, it cannot find out what is going on in the child object. Therefore, the context will be regarded as unchanged.
I then refactored the codes to be like this:
NSMutableDictionary *dict = entity.dict; [dict setObject:[obj_a copy] forKey:@"task"]; [dict setObject:[obj_b copy] forKey:@"info"]; [[NSManagedObjectContext contextForCurrentThread] saveToPersistentStoreAndAwait];