Core Data 中保存/获取数据的不一致

Posted

技术标签:

【中文标题】Core Data 中保存/获取数据的不一致【英文标题】:Inconsistency in Saving/Fetching Data in Core Data 【发布时间】:2017-05-31 08:10:17 【问题描述】:

我在这里的第一篇文章,直奔主题。

我遇到了一个问题,我不确定是保存数据还是获取数据。 这是我尝试将数据保存在我的实体“序列”中的代码。该实体由 2 个属性“seqForWk1CD”和“seqForWk2CD”组成。

AppDelegate *delegate = [[UIApplication sharedApplication]delegate];
NSManagedObjectContext *context = [delegate managedObjectContext];
SequenceMO *seqEntity = [NSEntityDescription 
insertNewObjectForEntityForName:@"Sequence" 
inManagedObjectContext:context];
// some other code
seqEntity.seqForWk1CD = arrForWk1;
seqEntity.seqForWk2CD = arrForWk2;
NSLog(@"%@", arrForWk1);
NSLog(@"%@", arrForWk2);
NSError *error = nil;
if (context != nil) 
    if ([context hasChanges] && ![context save:&error]) 
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
        
    

打印时,数组将始终显示数组的内容。

这是我尝试获取数据的地方。

AppDelegate *delegate = [[UIApplication sharedApplication]delegate];
NSManagedObjectContext *context = [delegate managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc]init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Sequence" inManagedObjectContext:context];
[request setEntity:entity];
NSError *error;
if(![context save:&error])
    NSLog(@"Error fetching. %@ %@", error, [error localizedDescription]);

NSUInteger count = [context countForFetchRequest:request error:&error];
if(count != 0)
    NSArray *fetchObj = [context executeFetchRequest:request error:&error];
    NSManagedObject *sequence = (NSManagedObject *)[fetchObj objectAtIndex:0];
    NSLog(@"1 - %@", sequence);
    arrForWk1 = [sequence valueForKey:@"seqForWk1CD"];
    NSLog(@"%@", arrForWk1);
    arrForWk2 = [sequence valueForKey:@"seqForWk2CD"];
    NSLog(@"%@", arrForWk2);

当我重新启动应用程序时出现问题。数组要么显示(空)两个数组,要么显示两个数组的内容。 if(![context save:&error]) 的 if 语句永远不会被触发。已经为实体添加了 NSManagedObject 的子类。

我也尝试在@interface 中声明 AppDelegate 并通过 [delegate saveContext]; 强制立即保存上下文。

这是进行保存的方法。 "check" 在 vi​​ewDidLoad 方法中被初始化为 0。 “arrForWk1”和“arrForWk2”都在@interface 声明。

- (IBAction)randomizeSequence:(UIButton *)sender  
   NSMutableArray *storeArray = [[NSMutableArray alloc] init];
   AppDelegate *delegate = [[UIApplication sharedApplication]delegate];
   NSManagedObjectContext *context = [delegate managedObjectContext];
   SequenceMO *seqEntity = [NSEntityDescription insertNewObjectForEntityForName:@"Sequence" inManagedObjectContext:context];
   BOOL record = NO;
   int x;

   for (int i=0; [storeArray count] < 9; i++) //Loop for generate different random values
    
       x = 1 + arc4random() % 9;//generating random number
       if(i==0)//for first time
       
        [storeArray addObject:[NSNumber numberWithInt:x]];
       
       else
       
          for (int j=0; j<= [storeArray count]-1; j++)
          
              if (x ==[[storeArray objectAtIndex:j] intValue])
                  record = YES;
          

          if (record == YES)
          
              record = NO;
          
          else
          
              [storeArray addObject:[NSNumber numberWithInt:x]];
          
       
    
    check++;
    if(check == 1 ) 
       arrForWk1 = storeArray;
       [self.wk1Seq reloadData];
    
    else if(check == 2) 
        arrForWk2 = storeArray;
        seqEntity.seqForWk1CD = arrForWk1;
        seqEntity.seqForWk2CD = arrForWk2;
        NSError *error = nil;
        if (context != nil) 
            if ([context hasChanges] && ![context save:&error]) 
                NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
                abort();
            
        

        [self.wk2Seq reloadData];

补充一点,数组的数据类型是 NSMutableArray,我正在尝试将它们存储到“Transformable”类型的属性中。

【问题讨论】:

插入对象后是否保存了上下文? 让我们继续聊天chat.***.com/rooms/145523/coredataissue 什么时候调用代码的第一个sn-p? 您的 storeArray 不包含任何内容。每次单击按钮时都会初始化 storeArray,并尝试将该数组保存在不包含任何对象的 coreData 中。 请仅在需要时初始化上下文,即检查值为2时 【参考方案1】:

经过研究,我设法解决了这个问题。我不确定它实际上是如何工作的,但我在尝试获取数据时通过重新排列代码来解决它。

AppDelegate *delegate = [[UIApplication sharedApplication]delegate];
NSManagedObjectContext *context = [delegate managedObjectContext];
NSEntityDescription *descriptor = [NSEntityDescription entityForName:@"Sequence" inManagedObjectContext:context];
NSFetchRequest *request = [[NSFetchRequest alloc]init];
request.entity = descriptor;
NSError *error;
NSArray *fetchObj = [context executeFetchRequest:request error:&error];
if(fetchObj == nil) 
    NSLog(@"Error occured when trying to fetch.");


else 
    if(fetchObj.count == 0) 
        NSLog(@"No objects saved");
    else 
        NSManagedObject *sequence = (NSManagedObject *)[fetchObj objectAtIndex:0];
        NSLog(@"1 - %@", sequence);
        arrForWk1 = [sequence valueForKey:@"seqForWk1CD"];
        NSLog(@"%@", arrForWk1);
        arrForWk2 = [sequence valueForKey:@"seqForWk2CD"];
        NSLog(@"%@", arrForWk2);
        NSLog(@"2 - %@", sequence);
     

我也试过两种保存数据的方法。在我尝试保存数据的if statement 中,我将NSMutableArrays 转换为NSArrays。

else if(check == 2) 
    test2 = storeArray;
    NSManagedObjectContext *context = [delegate managedObjectContext];
    SequenceMO *seqEntity = [NSEntityDescription insertNewObjectForEntityForName:@"Sequence" inManagedObjectContext:context];
    NSArray *tArr = [arrForWk1 copy];
    NSArray *tArr2 = [arrForWk2 copy];
    seqEntity.seqForWk1CD = tArr;
    seqEntity.seqForWk2CD = tArr2;
    NSError *error = nil;
    if (context != nil) 
        if ([context hasChanges] && ![context save:&error]) 
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
        
    

我尝试的第二种方法是使用Core Data not saving changes to Transformable property的答案

id temp = [seqEntity seqForWk1CD];
id temp2 = [seqEntity seqForWk2CD];
temp = arrForWk1;
temp2 = arrForWk2;
[seqEntity setSeqForWk1CD:temp];
[seqEntity setSeqForWk2CD:temp2];

显然它以某种方式起作用。

【讨论】:

以上是关于Core Data 中保存/获取数据的不一致的主要内容,如果未能解决你的问题,请参考以下文章

使用来自 Core Data 的日期获取记录

Core Data MagicalRecord:获取请求并保存在多线程中。锁定获取的对象?

如何使用 Core Data 从不相关的实体中获取数据?

使用 Swift 从 Core Data 中获取数据并在 UITextFields 中显示

使用 Core Data 获取生成“无法识别的选择器错误”?

Core Data - 批量处理获取结果的属性