核心数据不保存可转换的NSMutableDictionary

我有两个类:configuration文件和configuration。 configuration文件包含Config对象的NSSet。 Profile和Config都是NSManagedObject子类。

 @interface Profile : NSManagedObject @property (nonatomic, retain) NSString * name; @property (nonatomic, retain) NSSet *configs; - (void)print; @end 

这是Config类

 @interface Config : NSManagedObject @property (nonatomic, retain) NSString * otherdata; @property (nonatomic, retain) NSString * name; @property (nonatomic, retain) NSMutableDictionary *myDict; @property (nonatomic, retain) Profile *profile; - (void)print; @end 

字典myDict有NSString *键和值。 现在,当我对myDict进行任何更改时,我调用NSManagedObject保存方法,并且没有错误地正常工作。 只要我不杀应用程序,一切都按预期行事。

但是当我强制杀死应用程序(无论是在Xcode或通过双击主页button,并在底部的button行中杀死它),然后重新启动应用程序,myDict中的数据恢复到以前那里,即新数据实际上并没有保存。 它只是在我杀了应用程序之前似乎被保存。

myDict在xcdatamodeld文件中被列为Transformable。 我试过了,没有指定任何NSTransformer类。 我也试过它指定一个变压器类MyDictTransformer,并在configuration我加了这个代码:

在Config.h中:

 @interface MyDictTransformer : NSValueTransformer @end 

在Config.m中:

 @implementation MyDictTransformer + (Class)transformedValueClass { return [NSMutableDictionary class]; } + (BOOL)allowsReverseTransformation { return YES; } - (id)transformedValue:(id)value { return [NSKeyedArchiver archivedDataWithRootObject:value]; } - (id)reverseTransformedValue:(id)value { return [NSKeyedUnarchiver unarchiveObjectWithData:value]; } @end 

同样在Config.m的顶部,我有这样的:

 // // from: http://stackoverflow.com/questions/4089352/core-data-not-updating-a-transformable-attribute // + (void)initialize { if (self == [Config class]) { MyDictTransformer *transformer = [[MyDictTransformer alloc] init]; [NSValueTransformer setValueTransformer:transformer forName:@"MyDictTransformer"]; } } 

同样在AppDelegate中,在applicationDidEnterBackgroundapplicationWillTerminate我调用saveContext:

 - (void)saveContext { NSError *error = nil; NSManagedObjectContext *managedObjectContext = self.managedObjectContext; if (managedObjectContext != nil) { if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) { /* Replace this implementation with code to handle the error appropriately. abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. */ NSLog(@"Unresolved error %@, %@", error, [error userInfo]); abort(); } } } 

无论我尝试过什么,它都不会保存Config中的字典。 它保存了config.name之类的东西,而不是config.myDict。

A)我做错了什么? B)我怎样才能解决这个问题,即使我不得不使用一些其他数据结构而不是NSMutableDictionary来保存数据?

你已经声明myDict是一个大红旗的NSMutableDictionary

托pipe对象属性不应该是可变types

机会是,你使用myDict这样的东西:

 someConfig.myDict[@"someKey"] = @"someValue"; [context save:&error]; 

问题是,你没有调用someConfig的setter方法,所以你没有做任何事情来通知它一个属性已经改变。 即使你调用了save: :,上下文不会影响保存不变的对象。

严格地说,每当你改变myDict时候,你可能就会调用[someConfig didChangeValueForKey:@"myDict"] 。 我不会推荐它,因为它很容易忘记和容易出错。

最好把myDict声明为不可变的,像这样使用它:

 @property (nonatomic, retain) NSDictionary *myDict; ... NSMutableDictionary *updatedDict = [someConfig.myDict mutableCopy]; updatedDict[@"someKey"] = @"someValue"; someConfig.myDict = [updatedDict copy]; [context save:&error];