Mar*_*arc 4 core-data objective-c nsmanagedobjectcontext ios
我有两个类:Profile和Config.配置文件包含NSSet的Config对象.Profile和Config都是NSManagedObject子类.
@interface Profile : NSManagedObject
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSSet *configs;
- (void)print;
@end
Run Code Online (Sandbox Code Playgroud)
这是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
Run Code Online (Sandbox Code Playgroud)
字典myDict有NSString*键和值.现在当我对myDict进行任何更改时,我调用了NSManagedObjectsave方法,并且没有任何错误.只要我不杀死应用程序,一切都按预期运行.
但是当我强制杀死应用程序时(无论是在Xcode中还是通过双击主页按钮并在底部的按钮行中将其删除)然后重新启动应用程序,myDict中的数据将恢复为之前的状态,即新的数据实际上没有保存.它似乎只是在我杀死应用程序之前保存.
myDict在xcdatamodeld文件中列为Transformable.我没有指定任何NSTransformer课程就试过了.我也尝试过指定一个变换器类MyDictTransformer,在Config中我添加了这段代码:
在Config.h中:
@interface MyDictTransformer : NSValueTransformer
@end
Run Code Online (Sandbox Code Playgroud)
在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
Run Code Online (Sandbox Code Playgroud)
另外在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"];
}
}
Run Code Online (Sandbox Code Playgroud)
同样在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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
无论我尝试过什么,它都不会在Config中保存字典.它保存config.name之类的任何其他更改,但不保存在config.myDict中.
A)我做错了什么?B)我怎样才能解决这个问题,即使我必须使用其他数据结构而不是NSMutableDictionary保存数据?
小智 21
你已宣布myDict为NSMutableDictionary一个大红旗.
托管对象属性永远不应该是可变类型
有可能,你正在使用myDict这样的东西:
someConfig.myDict[@"someKey"] = @"someValue";
[context save:&error];
Run Code Online (Sandbox Code Playgroud)
问题是,你没有调用setter方法,someConfig因此你没有做任何事情来通知它属性已被更改.即使你正在调用save:,上下文也不会费心保存未更改的对象.
严格地说,[someConfig didChangeValueForKey:@"myDict"]每次改变时你都可以随时打电话myDict.我不推荐它,因为它很容易忘记并且容易出错.
最好将声明声明myDict为不可变并使用它如下:
@property (nonatomic, retain) NSDictionary *myDict;
...
NSMutableDictionary *updatedDict = [someConfig.myDict mutableCopy];
updatedDict[@"someKey"] = @"someValue";
someConfig.myDict = [updatedDict copy];
[context save:&error];
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3173 次 |
| 最近记录: |