如何更新核心数据中的可转换属性

Posted

技术标签:

【中文标题】如何更新核心数据中的可转换属性【英文标题】:How to update transformable attribute in core data 【发布时间】:2015-07-26 07:27:32 【问题描述】:

我处于需要更新核心数据中实体中的可转换属性的情况,直到现在我已经尝试了谷歌和堆栈溢出的所有可能答案,但没有取得任何成果。

这是我在核心数据中保存对象的方法,我保存的对象是 NSMutablDictionary 类型的对象。

-(void)didSaveToCoreData :(NSMutableDictionary *)newDict


@try 
    AppDelegate *appDelegate  = [[UIApplication sharedApplication]delegate];

    NSManagedObjectContext *context = appDelegate.managedObjectContext ;

    DataModelSupport *entity = [NSEntityDescription insertNewObjectForEntityForName:@"CPIEntity" inManagedObjectContext:context];


    if (newDict != nil) 

        [entity.fixed_Model removeAllObjects];
        entity.fixed_Model = newDict;
    

    NSError *error ;
    [context save:&error];
    if(error)
    
        NSLog(@"Error in Saving Data");
    
    else
    
        [self didFetchFromCoreDataModel];
        NSLog(@"Successfully saved");
    


@catch (NSException *exception) 
    [self spareMeFromTheCrash:exception];

@finally 




在此方法中,我第一次保存了 19 个键/值的字典对象,并且我在 didFetchFromCoreDataModel 方法中正确获取它,但是当我刷新数据并获取 18 个键/值的字典时,我保存了该字典在核心数据中使用相同的方法 didSaveToCoreData 并以相同的方式从 didFetchFromCoreDataModel 中获取它,但它仍然显示 19 个键/值

DataModelSupport 是 NSManagedObject 的子类。 在 DataModelSupport.h 中:

@property (nonatomic,weak) NSMutableDictionary *fixed_Model;

在 DataModelSupport.m 中:

@dynamic fixed_Model;

这就是 DataModelSupport 类。

现在在这个方法中,我从核心数据中获取相同的对象

-(void)didFetchFromCoreDataModel


@try 
    AppDelegate *appDelegate  = [[UIApplication sharedApplication]delegate];

    NSManagedObjectContext *context = appDelegate.managedObjectContext ;
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"CPIEntity" inManagedObjectContext:context];

    NSFetchRequest *request = [[NSFetchRequest alloc]init];
    [request setReturnsDistinctResults:YES];
    [request setReturnsObjectsAsFaults:NO];
    [request setResultType:NSDictionaryResultType];
    [request setEntity:entity];
    NSError *error ;

    NSArray *arr = [context executeFetchRequest:request error:&error];

    updatedfinalArr = [arr valueForKey:@"fixed_Model"];



    if(error)
    
        NSLog(@"Error");
    
    else
    

    


@catch (NSException *exception) 
    [self spareMeFromTheCrash:exception];

@finally 




这就是我的核心数据的样子:-

感谢任何帮助。

编辑

我现在在 didSaveToCoreData 方法中对我的代码进行了一些更改,我正在使用这行代码按名称获取实体

NSEntityDescription *descriptor = [NSEntityDescription entityForName:@"CPIEntity" inManagedObjectContext:context];

因此,我不会在每次调用 didSaveToCoreData 方法时创建新实体。

这就是我保存 NSMutlableDictionary 对象的方式

DataModelSupport *entity = [[DataModelSupport alloc]initWithEntity:descriptor insertIntoManagedObjectContext:context];
[entity.fixed_Model removeAllObjects]
entity.fixed_Model = newDict;

但我仍然没有得到正确的结果。 现在,当我使用 EDIT 部分中解释的上述过程刷新数据并保存它并获取它时,我得到了更新的数据,但它增加了对象的数量,就像我第一次尝试获取时我在数组中得到了 1 个对象,并且在第二次尝试时,我得到了 2 个对象,它是这样的,所以当添加新数据时,它不会更新它,而是将它添加到实体的 fixed_Model 属性中并增加对象的数量。

最后,现在我正在使用这行代码从 didFetchFromCoreDataModel 方法中的数组中获取最后一个和更新对象

NSDictionary *ddd = [[arr valueForKey:@"fixed_Model"]lastObject];
updatedfinalArr = [NSMutableArray arrayWithObject:ddd];

【问题讨论】:

我在答案中添加了一些示例代码。 【参考方案1】:

您的 save 方法每次都会创建一个新的 CPIEntity 对象。因此,除非您在代码中的其他位置删除旧对象,否则我怀疑您的 fetch 会返回几个对象,其中第一个对象在 fixed_Model 属性中具有包含 19 个键/值对的字典,而第二个/后续对象包含18 个键/值对。

保存时,应先尝试获取现有对象,如果结果为零,则创建一个新对象。然后将新/现有对象的fixed_Model 属性设置为您的新字典。

编辑

您每次仍在插入一个新对象 (DataModelSupport *entity = [[DataModelSupport alloc]initWithEntity:descriptor insertIntoManagedObjectContext:context];)。请参阅下面的“获取或创建”示例:

AppDelegate *appDelegate  = [[UIApplication sharedApplication]delegate];
NSManagedObjectContext *context = appDelegate.managedObjectContext ;
NSEntityDescription *descriptor = [NSEntityDescription entityForName:@"CPIEntity" inManagedObjectContext:context];
NSFetchRequest *request = [[NSFetchRequest alloc]init];
request.entity = descriptor;
NSError *error;
NSArray *results = [context executeFetchRequest:request error:&error];
if (results == nil) 
    // This implies an error has occurred.
    NSLog(@"Error from Core Data: %@", error);
 else 
    if (results.count == 0) 
        // No objects saved, create a new one...
        DataModelSupport *entity = [[DataModelSupport alloc]initWithEntity:descriptor insertIntoManagedObjectContext:context];            
        entity.fixed_Model = newDict;
     else 
        // At least one object saved.  There should be only one
        // so use the first... 
        DataModelSupport *entity = [results firstObject];
        entity.fixed_Model = newDict;
    

为了简单起见,我假设 newDict 不是 nil;酌情修改以处理这种情况。

【讨论】:

我已经实现了您的更改,现在对象已正确更新。感谢您分享时间和知识。【参考方案2】:

你能缩小问题的范围吗?

即。你能比较一下这两个字典吗?原来的有 19 个值,新的有 18 个值?

是否存在未被“删除”的特定条目?这可能意味着“删除”(或没有删除)的挑战。

或者,如果你完全替换内容,你会得到什么结果?

【讨论】:

以上是关于如何更新核心数据中的可转换属性的主要内容,如果未能解决你的问题,请参考以下文章

是否可以访问核心数据中的原始数据以获取可转换属性

更新核心数据中的属性[重复]

如何按 NSFetchedResultsController 中的可转换属性进行排序?

核心数据日期和布尔属性无法更新

核心数据 - 在对象中的多对关系更改属性后更新 UI

如何避免更改 NSBatchInsertRequest 中的属性值?