问题描述
我有两个类:Profile和Config。配置文件包含配置对象的NSSet。配置文件和配置都是 NSManagedObject
子类。
I have two classes: Profile and Config. A Profile contains an NSSet of Config objects. Both Profile and Config are NSManagedObject
subclasses.
@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
保存方法,工作正常没有错误。只要我不杀死应用程序,一切都如预期。
The dictionary myDict has NSString
*keys and values. Now when I make any changes to myDict, I call the NSManagedObject
save method and that works fine with no errors. As long as I do not kill the app, everything behaves as expected.
但是当我强制杀死应用程序(在Xcode或双击主页按钮和杀死它在底部的按钮行),然后重新启动应用程序,myDict中的数据还原到之前的那些,即新的数据没有实际保存。它只是在我杀死应用程序之前才被保存。
But when I force kill the app (either in Xcode or by double pressing the home button and killing it in the row of buttons at the bottom) and then restart the app, the data in myDict reverts to what was there before, ie the new data was not actually saved. It only appeared to be saved before I killed the app.
myDict在xcdatamodeld文件中列为Transformable。我试过没有指定任何 NSTransformer
类。我还尝试指定一个变换器类MyDictTransformer,并在配置我添加了这个代码:
myDict is listed as Transformable inside the xcdatamodeld file. I tried it without specifying any NSTransformer
class. I also tried it specifying a transformer class MyDictTransformer, and in Config I added this code:
在Config.h:
@interface MyDictTransformer : NSValueTransformer
@end
b $ b
在Config.m中:
In 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
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:
Also in AppDelegate, in both applicationDidEnterBackground
and applicationWillTerminate
I call 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。
No matter what I have tried, it simply does not save the dictionary in Config. It saves any other changes in things like config.name but not in config.myDict.
A)我做错了什么?
B)我如何解决这个问题,即使我必须使用一些 NSMutableDictionary
以外的其他数据结构来保存数据吗?
A) What am I doing wrong?B) How can I fix this, even if I have to use some other data structure than an NSMutableDictionary
to save the data?
推荐答案
您已将 myDict
声明为 NSMutableDictionary
这是一个大红旗。
You've declared myDict
as an NSMutableDictionary
which is a big red flag.
托管对象属性不能是可变类型
Managed object attributes should never be a mutable type
可能是您正在使用 myDict
这样的:
Chances are, you're using myDict
something like this:
someConfig.myDict[@"someKey"] = @"someValue";
[context save:&error];
问题是,你不是调用 someConfig
,所以你什么都没有通知它属性已被更改。即使你调用 save:
,上下文也不会干扰保存未更改的对象。
The problem is, you're not calling a setter method of someConfig
so you've done nothing to inform it that an attribute has been changed. And even though you're calling save:
, the context doesn't bother saving unchanged objects.
,每次更改 myDict
时,您可能会调用 [someConfig didChangeValueForKey:@myDict]
我不会推荐它,因为它很容易忘记和容易出错。
Strictly speaking, you could probably get away with calling [someConfig didChangeValueForKey:@"myDict"]
every time you change myDict
. I wouldn't recommend it though because it's easy to forget and error prone.
最好声明 myDict
as non-mutable and use it like this:
It would better to declare myDict
as non-mutable and use it like this:
@property (nonatomic, retain) NSDictionary *myDict;
...
NSMutableDictionary *updatedDict = [someConfig.myDict mutableCopy];
updatedDict[@"someKey"] = @"someValue";
someConfig.myDict = [updatedDict copy];
[context save:&error];
这篇关于Core Data不保存可变的NSMutableDictionary的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!