gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-11-01 05:01:15 26 4
gpt4 key购买 nike

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

@interface Profile : NSManagedObject

@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSSet *configs;

- (void)print;

@end

这是配置类

@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 中或通过双击主页按钮并在底部的按钮行中终止它)然后重新启动应用程序时,myDict 中的数据恢复到之前的状态,即新数据实际上并没有保存。它只是在我终止应用程序之前才出现保存。

myDict 在 xcdatamodeld 文件中列为 Transformable。我在没有指定任何 NSTransformer 类的情况下进行了尝试。我还尝试指定转换器类 MyDictTransformer,并在 Config 中添加以下代码:

在 Config.h 中:

@interface MyDictTransformer : NSValueTransformer

@end

在配置文件中:

@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,这是一个大危险信号。

托管对象属性绝不应该是可变类型

很有可能,您正在使用 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];

关于ios - 核心数据不保存可转换的 NSMutableDictionary,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22211633/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com