核心数据不保存可转换的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中,在applicationDidEnterBackground
和applicationWillTerminate
我调用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];